package wf.servitor.common.event import org.apache.activemq.artemis.api.core.Message import org.apache.activemq.artemis.api.core.RoutingType import org.apache.activemq.artemis.api.core.client.ClientMessage import org.apache.activemq.artemis.api.core.client.ClientSession import wf.servitor.common.Event import java.io.* import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock class Session(private val session: ClientSession, private val queue: String) { private val consumer by lazy { lock.withLock { session.start() } session.createConsumer(queue) } private val lock = ReentrantLock() private val producer by lazy { session.createProducer() } private fun makeMessage(routingType: RoutingType, obj: Event, group: String? = null): Message { return session.createMessage(true).also { it.routingType = routingType group?.let(it::setGroupID) val bbos = ByteArrayOutputStream() val oos = ObjectOutputStream(bbos) oos.writeObject(obj) it.bodyBuffer.writeBytes(bbos.toByteArray()) } } fun sendUpdate(update: Event.TaskUpdate) = lock.withLock { println("Sending update") println(update) producer.send( "servitor.observer", makeMessage(RoutingType.ANYCAST, update, "servitor.task.${update.task.id}") ) } fun queueTask(task: Event.Task) = lock.withLock { println("Sending task") println(task) producer.send( "servitor.task", makeMessage(RoutingType.ANYCAST, task, "servitor.task.${task.id}") ) } fun queueRelay(relay: Event.Relay) = lock.withLock { producer.send( "servitor.relay", makeMessage(RoutingType.ANYCAST, relay, "servitor.task.${relay.task.id}") ) } fun onMessage(block: (ClientMessage) -> Unit) { lock.withLock { consumer.setMessageHandler(block) } } fun close() { session.commit() session.close() } inline fun extract(message: ClientMessage): T { message.acknowledge() val byteArray = ByteArray(message.bodySize) message.bodyBuffer.readBytes(byteArray) val obj = ObjectInputStream(ByteArrayInputStream(byteArray)).readObject() if (obj !is T) { throw RuntimeException("Queue is FUCKED") } return obj } }