All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.enodeframework.messaging.impl.DefaultMessageDispatcher.kt Maven / Gradle / Ivy

There is a newer version: 1.1.10
Show newest version
package org.enodeframework.messaging.impl

import com.google.common.collect.Lists
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
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.ISerializeService
import org.enodeframework.infrastructure.IObjectProxy
import org.enodeframework.infrastructure.ITypeNameProvider
import org.enodeframework.messaging.*
import org.slf4j.LoggerFactory
import java.util.concurrent.CompletableFuture
import java.util.function.Consumer
import java.util.stream.Collectors

/**
 * @author [email protected]
 */
class DefaultMessageDispatcher(
        private val typeNameProvider: ITypeNameProvider,
        private val messageHandlerProvider: IMessageHandlerProvider,
        private val twoMessageHandlerProvider: ITwoMessageHandlerProvider,
        private val threeMessageHandlerProvider: IThreeMessageHandlerProvider,
        private val serializeService: ISerializeService
) : IMessageDispatcher {
    override fun dispatchMessageAsync(message: IMessage): 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)
        dispatchSingleMessage(queueMessageDispatching.dequeueMessage(), queueMessageDispatching)
        //如果有至少两个事件,则尝试调用针对两个事件的Handler
        if (messageCount >= 2) {
            val twoMessageHandlers = twoMessageHandlerProvider.getHandlers(messages.stream().map { x: IMessage -> x.javaClass }.collect(Collectors.toList()) as List>)
            if (twoMessageHandlers.isNotEmpty()) {
                dispatchMultiMessage(messages, twoMessageHandlers, rootDispatching) { multiMessageDispatching: MultiMessageDispatching, handlerProxy: IMessageHandlerProxy2, queueHandler: QueuedHandler?, retryTimes: Int -> dispatchTwoMessageToHandlerAsync(multiMessageDispatching, handlerProxy, queueHandler, retryTimes) }
            }
        }
        //如果有至少三个事件,则尝试调用针对三个事件的Handler
        if (messageCount >= 3) {
            val threeMessageHandlers = threeMessageHandlerProvider.getHandlers(messages.stream().map { x: IMessage -> x.javaClass }.collect(Collectors.toList()) as List>)
            if (threeMessageHandlers.isNotEmpty()) {
                dispatchMultiMessage(messages, threeMessageHandlers, rootDispatching) { multiMessageDispatching: MultiMessageDispatching, handlerProxy: IMessageHandlerProxy3, queueHandler: QueuedHandler?, retryTimes: Int -> dispatchThreeMessageToHandlerAsync(multiMessageDispatching, handlerProxy, queueHandler, retryTimes) }
            }
        }
        return rootDispatching.taskCompletionSource
    }

    fun dispatchSingleMessage(message: IMessage, queueMessageDispatching: QueueMessageDispatching) {
        val messageHandlerDataList = messageHandlerProvider.getHandlers(message.javaClass)
        if (messageHandlerDataList.isEmpty()) {
            queueMessageDispatching.onMessageHandled(message)
            return
        }
        messageHandlerDataList.forEach(Consumer { messageHandlerData: MessageHandlerData ->
            val singleMessageDispatching = SingleMessageDispatching(message, queueMessageDispatching, messageHandlerData.allHandlers, typeNameProvider)
            if (messageHandlerData.listHandlers.isNotEmpty()) {
                messageHandlerData.listHandlers.forEach { handler: IMessageHandlerProxy1 -> dispatchSingleMessageToHandlerAsync(singleMessageDispatching, handler, null, 0) }
            }
            if (messageHandlerData.queuedHandlers.isNotEmpty()) {
                val queueHandler = QueuedHandler(messageHandlerData.queuedHandlers) { queuedHandler: QueuedHandler?, nextHandler: IMessageHandlerProxy1 -> 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(Consumer { messageHandlerData: MessageHandlerData ->
            val multiMessageDispatching = MultiMessageDispatching(messages, messageHandlerData.allHandlers, rootDispatching, typeNameProvider)
            if (messageHandlerData.listHandlers.isNotEmpty()) {
                messageHandlerData.listHandlers.forEach(Consumer { 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: IMessageHandlerProxy1, 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: IMessageHandlerProxy2, 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: IMessageHandlerProxy3, 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: IMessageHandlerProxy1, handlerTypeName: String, messageTypeName: String, queueHandler: QueuedHandler?, retryTimes: Int) {
        val message = singleMessageDispatching.message
        IOHelper.tryAsyncActionRecursivelyWithoutResult("HandleSingleMessageAsync", {
            CoroutineScope(Dispatchers.IO).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: IMessageHandlerProxy2, handlerTypeName: String, queueHandler: QueuedHandler?, retryTimes: Int) {
        val messages = multiMessageDispatching.messages
        val message1 = messages[0]
        val message2 = messages[1]
        IOHelper.tryAsyncActionRecursively("HandleTwoMessageAsync", {
            CoroutineScope(Dispatchers.IO).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: IMessageHandlerProxy3, 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(Dispatchers.IO).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)
    }

    companion object {
        private val logger = LoggerFactory.getLogger(DefaultMessageDispatcher::class.java)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy