EventHandlerGroup<T> createEventProcessors( final Sequence[] barrierSequences, final EventProcessorFactory<T>[] processorFactories) { final EventProcessor[] eventProcessors = new EventProcessor[processorFactories.length]; for (int i = 0; i < processorFactories.length; i++) { eventProcessors[i] = processorFactories[i].createEventProcessor(ringBuffer, barrierSequences); } return handleEventsWith(eventProcessors); }
public void unMarkEventProcessorsAsEndOfChain(final Sequence... barrierEventProcessors) { for (Sequence barrierEventProcessor : barrierEventProcessors) { getEventProcessorInfo(barrierEventProcessor).markAsUsedInBarrier(); } }
public SequenceBarrier getBarrierFor(final EventHandler<T> handler) { final ConsumerInfo consumerInfo = getEventProcessorInfo(handler); return consumerInfo != null ? consumerInfo.getBarrier() : null; }
public static void main(String[] args) { Disruptor<MyEvent> disruptor = new Disruptor<MyEvent>(factory, 1024, DaemonThreadFactory.INSTANCE); disruptor.handleEventsWith(handler1).then(handler2).then(handler3); disruptor.start(); } }
@Test(expected = TimeoutException.class, timeout = 2000) public void shouldThrowTimeoutExceptionIfShutdownDoesNotCompleteNormally() throws Exception { //Given final DelayedEventHandler delayedEventHandler = createDelayedEventHandler(); disruptor.handleEventsWith(delayedEventHandler); publishEvent(); //When disruptor.shutdown(1, SECONDS); //Then }
@Test public void shouldWaitUntilAllFirstEventProcessorsProcessEventBeforeMakingItAvailableToDependentEventProcessors() throws Exception { DelayedEventHandler eventHandler1 = createDelayedEventHandler(); CountDownLatch countDownLatch = new CountDownLatch(2); EventHandler<TestEvent> eventHandler2 = new EventHandlerStub<TestEvent>(countDownLatch); disruptor.handleEventsWith(eventHandler1).then(eventHandler2); ensureTwoEventsProcessedAccordingToDependencies(countDownLatch, eventHandler1); }
@Test public void shouldWaitOnAllProducersJoinedByAnd() throws Exception { DelayedEventHandler handler1 = createDelayedEventHandler(); DelayedEventHandler handler2 = createDelayedEventHandler(); CountDownLatch countDownLatch = new CountDownLatch(2); EventHandler<TestEvent> handlerWithBarrier = new EventHandlerStub<TestEvent>(countDownLatch); disruptor.handleEventsWith(handler1); final EventHandlerGroup<TestEvent> handler2Group = disruptor.handleEventsWith(handler2); disruptor.after(handler1).and(handler2Group).handleEventsWith(handlerWithBarrier); ensureTwoEventsProcessedAccordingToDependencies(countDownLatch, handler1, handler2); }
@Test public void shouldProvideEventsToWorkHandlers() throws Exception { final TestWorkHandler workHandler1 = createTestWorkHandler(); final TestWorkHandler workHandler2 = createTestWorkHandler(); disruptor.handleEventsWithWorkerPool(workHandler1, workHandler2); publishEvent(); publishEvent(); workHandler1.processEvent(); workHandler2.processEvent(); }
@Test public void shouldProvideEventsMultipleWorkHandlers() throws Exception { final TestWorkHandler workHandler1 = createTestWorkHandler(); final TestWorkHandler workHandler2 = createTestWorkHandler(); final TestWorkHandler workHandler3 = createTestWorkHandler(); final TestWorkHandler workHandler4 = createTestWorkHandler(); final TestWorkHandler workHandler5 = createTestWorkHandler(); final TestWorkHandler workHandler6 = createTestWorkHandler(); final TestWorkHandler workHandler7 = createTestWorkHandler(); final TestWorkHandler workHandler8 = createTestWorkHandler(); disruptor .handleEventsWithWorkerPool(workHandler1, workHandler2) .thenHandleEventsWithWorkerPool(workHandler3, workHandler4); disruptor .handleEventsWithWorkerPool(workHandler5, workHandler6) .thenHandleEventsWithWorkerPool(workHandler7, workHandler8); }
EventHandlerGroup<T> createWorkerPool( final Sequence[] barrierSequences, final WorkHandler<? super T>[] workHandlers) { final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(barrierSequences); final WorkerPool<T> workerPool = new WorkerPool<>(ringBuffer, sequenceBarrier, exceptionHandler, workHandlers); consumerRepository.add(workerPool, sequenceBarrier); final Sequence[] workerSequences = workerPool.getWorkerSequences(); updateGatingSequencesForNextInChain(barrierSequences, workerSequences); return new EventHandlerGroup<>(this, consumerRepository, workerSequences); }
@Test(expected = IllegalArgumentException.class) public void shouldThrowExceptionIfHandlerIsNotAlreadyConsuming() throws Exception { disruptor.after(createDelayedEventHandler()).handleEventsWith(createDelayedEventHandler()); }
public EventProcessor getEventProcessorFor(final EventHandler<T> handler) { final EventProcessorInfo<T> eventprocessorInfo = getEventProcessorInfo(handler); if (eventprocessorInfo == null) { throw new IllegalArgumentException("The event handler " + handler + " is not processing events."); } return eventprocessorInfo.getEventProcessor(); }
/** * Create a group of event processors to be used as a dependency. * * @param processors the event processors, previously set up with {@link #handleEventsWith(com.lmax.disruptor.EventProcessor...)}, * that will form the barrier for subsequent handlers or processors. * @return an {@link EventHandlerGroup} that can be used to setup a {@link SequenceBarrier} over the specified event processors. * @see #after(com.lmax.disruptor.EventHandler[]) */ public EventHandlerGroup<T> after(final EventProcessor... processors) { for (final EventProcessor processor : processors) { consumerRepository.add(processor); } return new EventHandlerGroup<>(this, consumerRepository, Util.getSequencesFor(processors)); }
/** * <p>Starts the event processors and returns the fully configured ring buffer.</p> * * <p>The ring buffer is set up to prevent overwriting any entry that is yet to * be processed by the slowest event processor.</p> * * <p>This method must only be called once after all event processors have been added.</p> * * @return the configured ring buffer. */ public RingBuffer<T> start() { checkOnlyStartedOnce(); for (final ConsumerInfo consumerInfo : consumerRepository) { consumerInfo.start(executor); } return ringBuffer; }
/** * Get the {@link SequenceBarrier} used by a specific handler. Note that the {@link SequenceBarrier} * may be shared by multiple event handlers. * * @param handler the handler to get the barrier for. * @return the SequenceBarrier used by <i>handler</i>. */ public SequenceBarrier getBarrierFor(final EventHandler<T> handler) { return consumerRepository.getBarrierFor(handler); }
/** * Calls {@link com.lmax.disruptor.EventProcessor#halt()} on all of the event processors created via this disruptor. */ public void halt() { for (final ConsumerInfo consumerInfo : consumerRepository) { consumerInfo.halt(); } }
/** * Override the default exception handler for a specific handler. * <pre>disruptorWizard.handleExceptionsIn(eventHandler).with(exceptionHandler);</pre> * * @param eventHandler the event handler to set a different exception handler for. * @return an ExceptionHandlerSetting dsl object - intended to be used by chaining the with method call. */ public ExceptionHandlerSetting<T> handleExceptionsFor(final EventHandler<T> eventHandler) { return new ExceptionHandlerSetting<>(eventHandler, consumerRepository); }
@Override public String toString() { return "BasicExecutor{" + "threads=" + dumpThreadInfo() + '}'; }
@Test public void shouldAllowChainingEventHandlersWithSuperType() throws Exception { final CountDownLatch latch = new CountDownLatch(2); final DelayedEventHandler delayedEventHandler = createDelayedEventHandler(); final EventHandler<Object> objectHandler = new EventHandlerStub<Object>(latch); disruptor.handleEventsWith(delayedEventHandler).then(objectHandler); ensureTwoEventsProcessedAccordingToDependencies(latch, delayedEventHandler); }
@Test public void shouldAllowSpecifyingSpecificEventProcessorsToWaitFor() throws Exception { DelayedEventHandler handler1 = createDelayedEventHandler(); DelayedEventHandler handler2 = createDelayedEventHandler(); CountDownLatch countDownLatch = new CountDownLatch(2); EventHandler<TestEvent> handlerWithBarrier = new EventHandlerStub<TestEvent>(countDownLatch); disruptor.handleEventsWith(handler1, handler2); disruptor.after(handler1, handler2).handleEventsWith(handlerWithBarrier); ensureTwoEventsProcessedAccordingToDependencies(countDownLatch, handler1, handler2); }