Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.enodeframework.messaging.impl.DefaultMessageDispatcher.kt Maven / Gradle / Ivy
package org.enodeframework.messaging.impl
import com.google.common.collect.Lists
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.future.asCompletableFuture
import org.enodeframework.common.function.Action4
import org.enodeframework.common.io.IOHelper
import org.enodeframework.common.io.Task
import org.enodeframework.common.serializing.SerializeService
import org.enodeframework.infrastructure.ObjectProxy
import org.enodeframework.infrastructure.TypeNameProvider
import org.enodeframework.messaging.Message
import org.enodeframework.messaging.MessageDispatcher
import org.enodeframework.messaging.MessageHandlerData
import org.enodeframework.messaging.MessageHandlerProvider
import org.enodeframework.messaging.MessageHandlerProxy1
import org.enodeframework.messaging.MessageHandlerProxy2
import org.enodeframework.messaging.MessageHandlerProxy3
import org.enodeframework.messaging.ThreeMessageHandlerProvider
import org.enodeframework.messaging.TwoMessageHandlerProvider
import org.slf4j.LoggerFactory
import java.util.concurrent.CompletableFuture
/**
* @author [email protected]
*/
class DefaultMessageDispatcher(
private val typeNameProvider: TypeNameProvider,
private val messageHandlerProvider: MessageHandlerProvider,
private val twoMessageHandlerProvider: TwoMessageHandlerProvider,
private val threeMessageHandlerProvider: ThreeMessageHandlerProvider,
private val serializeService: SerializeService,
private val coroutineDispatcher: CoroutineDispatcher,
) : MessageDispatcher {
override fun dispatchMessageAsync(message: Message): CompletableFuture {
return dispatchMessages(Lists.newArrayList(message))
}
override fun dispatchMessagesAsync(messages: List): CompletableFuture {
return dispatchMessages(messages)
}
private fun dispatchMessages(messages: List): CompletableFuture {
val messageCount = messages.size
if (messageCount == 0) {
return Task.completedTask
}
val rootDispatching = RootDispatching()
// 先对每个事件调用其Handler
val queueMessageDispatching = QueueMessageDispatching(this, rootDispatching, messages)
val message = queueMessageDispatching.dequeueMessage() ?: return Task.completedTask
dispatchSingleMessage(message, queueMessageDispatching)
//如果有至少两个事件,则尝试调用针对两个事件的Handler
if (messageCount >= 2) {
val twoMessageHandlers =
twoMessageHandlerProvider.getHandlers(messages.map { x: Message -> x.javaClass }.toList())
if (twoMessageHandlers.isNotEmpty()) {
dispatchMultiMessage(
messages, twoMessageHandlers, rootDispatching
) { multiMessageDispatching: MultiMessageDispatching, handlerProxy: MessageHandlerProxy2, queueHandler: QueuedHandler?, retryTimes: Int ->
dispatchTwoMessageToHandlerAsync(
multiMessageDispatching, handlerProxy, queueHandler, retryTimes
)
}
}
}
//如果有至少三个事件,则尝试调用针对三个事件的Handler
if (messageCount >= 3) {
val threeMessageHandlers =
threeMessageHandlerProvider.getHandlers(messages.map { x: Message -> x.javaClass }.toList())
if (threeMessageHandlers.isNotEmpty()) {
dispatchMultiMessage(
messages, threeMessageHandlers, rootDispatching
) { multiMessageDispatching: MultiMessageDispatching, handlerProxy: MessageHandlerProxy3, queueHandler: QueuedHandler?, retryTimes: Int ->
dispatchThreeMessageToHandlerAsync(
multiMessageDispatching, handlerProxy, queueHandler, retryTimes
)
}
}
}
return rootDispatching.taskCompletionSource
}
fun dispatchSingleMessage(message: Message, queueMessageDispatching: QueueMessageDispatching) {
val messageHandlerDataList = messageHandlerProvider.getHandlers(message.javaClass)
if (messageHandlerDataList.isEmpty()) {
queueMessageDispatching.onMessageHandled(message)
return
}
messageHandlerDataList.forEach { messageHandlerData: MessageHandlerData ->
val singleMessageDispatching = SingleMessageDispatching(
message, queueMessageDispatching, messageHandlerData.allHandlers, typeNameProvider
)
if (messageHandlerData.listHandlers.isNotEmpty()) {
messageHandlerData.listHandlers.forEach { handler: MessageHandlerProxy1 ->
dispatchSingleMessageToHandlerAsync(
singleMessageDispatching, handler, null, 0
)
}
}
if (messageHandlerData.queuedHandlers.isNotEmpty()) {
val queueHandler =
QueuedHandler(messageHandlerData.queuedHandlers) { queuedHandler: QueuedHandler?, nextHandler: MessageHandlerProxy1 ->
dispatchSingleMessageToHandlerAsync(
singleMessageDispatching, nextHandler, queuedHandler, 0
)
}
dispatchSingleMessageToHandlerAsync(
singleMessageDispatching, queueHandler.dequeueHandler(), queueHandler, 0
)
}
}
}
private fun dispatchMultiMessage(
messages: List,
messageHandlerDataList: List>,
rootDispatching: RootDispatching,
dispatchAction: Action4?, Int>
) {
messageHandlerDataList.forEach { messageHandlerData: MessageHandlerData ->
val multiMessageDispatching =
MultiMessageDispatching(messages, messageHandlerData.allHandlers, rootDispatching, typeNameProvider)
if (messageHandlerData.listHandlers.isNotEmpty()) {
messageHandlerData.listHandlers.forEach { handler: T ->
dispatchAction.apply(
multiMessageDispatching, handler, null, 0
)
}
}
if (messageHandlerData.queuedHandlers.isNotEmpty()) {
val queuedHandler =
QueuedHandler(messageHandlerData.queuedHandlers) { currentQueuedHandler: QueuedHandler?, nextHandler: T ->
dispatchAction.apply(
multiMessageDispatching, nextHandler, currentQueuedHandler, 0
)
}
dispatchAction.apply(multiMessageDispatching, queuedHandler.dequeueHandler(), queuedHandler, 0)
}
}
}
private fun dispatchSingleMessageToHandlerAsync(
singleMessageDispatching: SingleMessageDispatching,
handlerProxy: MessageHandlerProxy1,
queueHandler: QueuedHandler?,
retryTimes: Int
) {
val message = singleMessageDispatching.message
val messageTypeName = typeNameProvider.getTypeName(message.javaClass)
val handlerType: Class<*> = handlerProxy.getInnerObject().javaClass
val handlerTypeName = typeNameProvider.getTypeName(handlerType)
handleSingleMessageAsync(
singleMessageDispatching, handlerProxy, handlerTypeName, messageTypeName, queueHandler, retryTimes
)
}
private fun dispatchTwoMessageToHandlerAsync(
multiMessageDispatching: MultiMessageDispatching,
handlerProxy: MessageHandlerProxy2,
queueHandler: QueuedHandler?,
retryTimes: Int
) {
val handlerType: Class<*> = handlerProxy.getInnerObject().javaClass
val handlerTypeName = typeNameProvider.getTypeName(handlerType)
handleTwoMessageAsync(multiMessageDispatching, handlerProxy, handlerTypeName, queueHandler, 0)
}
private fun dispatchThreeMessageToHandlerAsync(
multiMessageDispatching: MultiMessageDispatching,
handlerProxy: MessageHandlerProxy3,
queueHandler: QueuedHandler?,
retryTimes: Int
) {
val handlerType: Class<*> = handlerProxy.getInnerObject().javaClass
val handlerTypeName = typeNameProvider.getTypeName(handlerType)
handleThreeMessageAsync(multiMessageDispatching, handlerProxy, handlerTypeName, queueHandler, 0)
}
private fun handleSingleMessageAsync(
singleMessageDispatching: SingleMessageDispatching,
handlerProxy: MessageHandlerProxy1,
handlerTypeName: String,
messageTypeName: String,
queueHandler: QueuedHandler?,
retryTimes: Int
) {
val message = singleMessageDispatching.message
IOHelper.tryAsyncActionRecursivelyWithoutResult("HandleSingleMessageAsync", {
CoroutineScope(coroutineDispatcher).async {
handlerProxy.handleAsync(message)
}.asCompletableFuture()
}, {
singleMessageDispatching.removeHandledHandler(handlerTypeName)
queueHandler?.onHandlerFinished(handlerProxy)
if (logger.isDebugEnabled) {
logger.debug("message handled success, messages: {}", serializeService.serialize(message))
}
}, {
String.format(
"[message: %s, handlerType: %s]",
serializeService.serialize(message),
handlerProxy.getInnerObject().javaClass.name
)
}, null, retryTimes, true)
}
private fun handleTwoMessageAsync(
multiMessageDispatching: MultiMessageDispatching,
handlerProxy: MessageHandlerProxy2,
handlerTypeName: String,
queueHandler: QueuedHandler?,
retryTimes: Int
) {
val messages = multiMessageDispatching.messages
val message1 = messages[0]
val message2 = messages[1]
IOHelper.tryAsyncActionRecursively("HandleTwoMessageAsync", {
CoroutineScope(coroutineDispatcher).async {
handlerProxy.handleAsync(message1, message2)
}.asCompletableFuture()
}, {
multiMessageDispatching.removeHandledHandler(handlerTypeName)
queueHandler?.onHandlerFinished(handlerProxy)
if (logger.isDebugEnabled) {
logger.debug("TwoMessage handled success, messages: {}", serializeService.serialize(messages))
}
}, {
String.format(
"[messages: %s, handlerType: %s]",
serializeService.serialize(messages),
handlerProxy.getInnerObject().javaClass.name
)
}, null, retryTimes, true)
}
private fun handleThreeMessageAsync(
multiMessageDispatching: MultiMessageDispatching,
handlerProxy: MessageHandlerProxy3,
handlerTypeName: String,
queueHandler: QueuedHandler?,
retryTimes: Int
) {
val messages = multiMessageDispatching.messages
val message1 = messages[0]
val message2 = messages[1]
val message3 = messages[2]
IOHelper.tryAsyncActionRecursively("HandleThreeMessageAsync", {
CoroutineScope(coroutineDispatcher).async {
handlerProxy.handleAsync(message1, message2, message3)
}.asCompletableFuture()
}, {
multiMessageDispatching.removeHandledHandler(handlerTypeName)
queueHandler?.onHandlerFinished(handlerProxy)
if (logger.isDebugEnabled) {
logger.debug("ThreeMessage handled success, messages: {}", serializeService.serialize(messages))
}
}, {
String.format(
"[messages: %s, handlerType: %s]",
serializeService.serialize(messages),
handlerProxy.getInnerObject().javaClass.name
)
}, null, retryTimes, true)
}
private val logger = LoggerFactory.getLogger(DefaultMessageDispatcher::class.java)
}