You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.5 KiB
Kotlin

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 <reified T : Serializable> 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
}
}