package io.nuls.event.bus.utils.disruptor; import com.lmax.disruptor.*; import com.lmax.disruptor.dsl.Disruptor; import com.lmax.disruptor.dsl.ProducerType; import io.nuls.core.constant.ErrorCode; import io.nuls.core.exception.NulsRuntimeException; import io.nuls.core.module.service.ModuleService; import io.nuls.core.thread.manager.NulsThreadFactory; import io.nuls.core.utils.log.Log; import io.nuls.core.utils.param.AssertUtil; import io.nuls.event.bus.module.impl.EventBusModuleBootstrap; import io.nuls.event.bus.processor.manager.ProcessData; import java.util.HashMap; import java.util.Map; /** * @author Niels * @date 2017/10/10 */ public class DisruptorUtil<T extends DisruptorEvent> { private static final DisruptorUtil INSTANCE = new DisruptorUtil(); private static final Map<String, Disruptor<DisruptorEvent>> DISRUPTOR_MAP = new HashMap<>(); public static DisruptorUtil getInstance() { return INSTANCE; } private DisruptorUtil() { } private static final EventFactory EVENT_FACTORY = new EventFactory() { @Override public Object newInstance() { return new DisruptorEvent(); } }; /** * create a disruptor * * @param name The title of the disruptor * @param ringBufferSize The size of ringBuffer */ public void createDisruptor(String name, int ringBufferSize) { if (DISRUPTOR_MAP.keySet().contains(name)) { throw new NulsRuntimeException(ErrorCode.FAILED, "create disruptor faild,the name is repetitive!"); } Disruptor<DisruptorEvent> disruptor = new Disruptor<DisruptorEvent>(EVENT_FACTORY, ringBufferSize, new NulsThreadFactory(ModuleService.getInstance().getModuleId(EventBusModuleBootstrap.class),name), ProducerType.SINGLE, new SleepingWaitStrategy()); disruptor.handleEventsWith(new EventHandler<DisruptorEvent>() { @Override public void onEvent(DisruptorEvent disruptorEvent, long l, boolean b) throws Exception { Log.debug(disruptorEvent.getData() + ""); } }); DISRUPTOR_MAP.put(name, disruptor); } /** * start a disruptor service * * @param name */ public void start(String name) { Disruptor<DisruptorEvent> disruptor = DISRUPTOR_MAP.get(name); AssertUtil.canNotEmpty(disruptor, "the disruptor is not exist!name:" + name); disruptor.start(); } /** * start a disruptor service * * @param name */ public void shutdown(String name) { Disruptor<DisruptorEvent> disruptor = DISRUPTOR_MAP.get(name); AssertUtil.canNotEmpty(disruptor, "the disruptor is not exist!name:" + name); disruptor.shutdown(); } /** * add the data obj to the disruptor named the field name * * @param name * @param obj */ public void offer(String name, Object obj) { Disruptor<DisruptorEvent> disruptor = DISRUPTOR_MAP.get(name); AssertUtil.canNotEmpty(disruptor, "the disruptor is not exist!name:" + name); RingBuffer<DisruptorEvent> ringBuffer = disruptor.getRingBuffer(); //请求下一个事件序号; long sequence = ringBuffer.next(); try { //获取该序号对应的事件对象; DisruptorEvent event = ringBuffer.get(sequence); event.setData(obj); } finally { //发布事件; ringBuffer.publish(sequence); } } /** * add some handler to worker pool of the disruptor * * @param name * @param handler */ public void handleEventsWithWorkerPool(String name, WorkHandler<DisruptorEvent<ProcessData>>... handler) { Disruptor disruptor = DISRUPTOR_MAP.get(name); AssertUtil.canNotEmpty(disruptor, "the disruptor is not exist!name:" + name); disruptor.handleEventsWithWorkerPool(handler); } }