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

pro.jk.ejoker.messaging.impl.DefaultMessageDispatcher Maven / Gradle / Ivy

package pro.jk.ejoker.messaging.impl;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pro.jk.ejoker.common.context.annotation.context.Dependence;
import pro.jk.ejoker.common.context.annotation.context.EInitialize;
import pro.jk.ejoker.common.context.annotation.context.EService;
import pro.jk.ejoker.common.system.enhance.StringUtilx;
import pro.jk.ejoker.common.system.extension.AsyncWrapperException;
import pro.jk.ejoker.common.system.extension.acrossSupport.EJokerFutureUtil;
import pro.jk.ejoker.common.system.functional.IFunction;
import pro.jk.ejoker.common.system.functional.IVoidFunction2;
import pro.jk.ejoker.common.system.task.context.SystemAsyncHelper;
import pro.jk.ejoker.common.system.task.io.IOHelper;
import pro.jk.ejoker.common.system.wrapper.CountDownLatchWrapper;
import pro.jk.ejoker.messaging.IMessage;
import pro.jk.ejoker.messaging.IMessageDispatcher;
import pro.jk.ejoker.messaging.IMessageHandlerProxy;
import pro.jk.ejoker.utils.handlerProviderHelper.containers.MessageHandlerPool;

@EService
public class DefaultMessageDispatcher implements IMessageDispatcher {

	private final static Logger logger = LoggerFactory.getLogger(DefaultMessageDispatcher.class);
	
	@Dependence
	private IOHelper ioHelper;
	
	@Dependence
	private SystemAsyncHelper systemAsyncHelper;
	
	@Dependence
	private MessageHandlerPool messageHandlerPool;
	
	private IVoidFunction2>, String> multiMsgIoHandle = null;
	
	@EInitialize
	private void eInit() {
		multiMsgIoHandle = (mainAction, cxtInfo) -> systemAsyncHelper.submit(() -> ioHelper.tryAsyncAction2(
				"HandleMultiMessageAsync",
				mainAction::trigger,
				() -> {},
				() -> cxtInfo,
				true)
			);
	}
	
	@Override
	public Future dispatchMessageAsync(IMessage message) {

		List handlers = messageHandlerPool.getProxyAsyncHandlers(message.getClass());
		if(null != handlers && !handlers.isEmpty()) {
			Object countDownLatchHandle = CountDownLatchWrapper.newCountDownLatch(handlers.size());
			
			for(IMessageHandlerProxy proxyAsyncHandler:handlers) {
				systemAsyncHelper.submit(() -> ioHelper.tryAsyncAction2(
							"HandleSingleMessageAsync",
							() -> proxyAsyncHandler.handleAsync(message),
							r -> CountDownLatchWrapper.countDown(countDownLatchHandle),
							() -> StringUtilx.fmt("[messageType: {}, messageId: {}, handlerType: {}]",
									message.getClass().getSimpleName(),
									message.getId(),
									proxyAsyncHandler.toString()
								),
							ex -> logger.error("Handle single message has unknown exception, the framework should not be run to here!!!",
										ex),
							true)
				);
			}
			
			try {
				CountDownLatchWrapper.await(countDownLatchHandle);
			} catch (InterruptedException e) {
				throw new AsyncWrapperException(e);
			}
		}
		return EJokerFutureUtil.completeFuture();
	}

	@Override
	public Future dispatchMessagesAsync(Collection messages) {
		
		if(null == messages || messages.isEmpty()) {
			throw new RuntimeException("null == messages || messages.isEmpty() !!!");
		}
		
		IMessage[] msgArray = messages.toArray(tRef);
		
		// 1个Message属于绝大多数情况,值得单独列出
		if(1 == msgArray.length)
			return dispatchMessageAsync(msgArray[0]);

		/// TODO 此处的异步语义是等待全部指派完成才返回?
		/// 还是只要有一个完成就返回?
		/// 还是执行到此就返回?
		return systemAsyncHelper.submit(() -> {

			// 适配多个message的handler
			// ...
			messageHandlerPool.processMultiMessages(multiMsgIoHandle, msgArray);
			
		});
		
	}

	private final static IMessage[] tRef = new IMessage[0];
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy