/** * <p>Set up custom event processors to handle events from the ring buffer. The Disruptor will * automatically start these processors when {@link Disruptor#start()} is called.</p> * * <p>This method is generally used as part of a chain. For example if the handler <code>A</code> must * process events before handler <code>B</code>:</p> * * @param eventProcessorFactories the event processor factories to use to create the event processors that will process events. * @return a {@link EventHandlerGroup} that can be used to chain dependencies. */ @SafeVarargs public final EventHandlerGroup<T> then(final EventProcessorFactory<T>... eventProcessorFactories) { return handleEventsWith(eventProcessorFactories); }
/** * Create a new event handler group that combines the consumers in this group with <code>otherHandlerGroup</code>. * * @param otherHandlerGroup the event handler group to combine. * @return a new EventHandlerGroup combining the existing and new consumers into a single dependency group. */ public EventHandlerGroup<T> and(final EventHandlerGroup<T> otherHandlerGroup) { final Sequence[] combinedSequences = new Sequence[this.sequences.length + otherHandlerGroup.sequences.length]; System.arraycopy(this.sequences, 0, combinedSequences, 0, this.sequences.length); System.arraycopy( otherHandlerGroup.sequences, 0, combinedSequences, this.sequences.length, otherHandlerGroup.sequences.length); return new EventHandlerGroup<>(disruptor, consumerRepository, combinedSequences); }
@Test public void shouldSupportCustomProcessorsAndHandlersAsDependencies() throws Exception { final DelayedEventHandler delayedEventHandler1 = createDelayedEventHandler(); final DelayedEventHandler delayedEventHandler2 = createDelayedEventHandler(); disruptor.handleEventsWith(delayedEventHandler1); RingBuffer<TestEvent> ringBuffer = disruptor.getRingBuffer(); CountDownLatch countDownLatch = new CountDownLatch(2); EventHandler<TestEvent> handlerWithBarrier = new EventHandlerStub<TestEvent>(countDownLatch); final SequenceBarrier sequenceBarrier = disruptor.after(delayedEventHandler1).asSequenceBarrier(); final BatchEventProcessor<TestEvent> processor = new BatchEventProcessor<TestEvent>(ringBuffer, sequenceBarrier, delayedEventHandler2); disruptor.after(delayedEventHandler1).and(processor).handleEventsWith(handlerWithBarrier); ensureTwoEventsProcessedAccordingToDependencies(countDownLatch, delayedEventHandler1, delayedEventHandler2); }
@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); }
.handleEventsWith(journallingHandler); .handleEventsWith((rb, bs) -> { procR1 = new MasterProcessor(rb, rb.newBarrier(bs), handlerR1); return procR1; }); disruptor.after(procR1).handleEventsWith(matchingEngineHandler); .then(resultsHandler); .then((rb, bs) -> { procR2 = new SlaveProcessor<>(rb, rb.newBarrier(bs), handlerR2); procR1.setSlaveProcessor(procR2);
@Test public void shouldSupportCombiningWorkerPoolWithEventHandlerAsDependencyWhenNotPreviouslyRegistered() throws Exception { final TestWorkHandler workHandler1 = createTestWorkHandler(); final DelayedEventHandler delayedEventHandler1 = createDelayedEventHandler(); final DelayedEventHandler delayedEventHandler2 = createDelayedEventHandler(); disruptor .handleEventsWith(delayedEventHandler1) .and(disruptor.handleEventsWithWorkerPool(workHandler1)) .then(delayedEventHandler2); publishEvent(); publishEvent(); delayedEventHandler1.processEvent(); delayedEventHandler1.processEvent(); workHandler1.processEvent(); delayedEventHandler2.processEvent(); workHandler1.processEvent(); delayedEventHandler2.processEvent(); }
/** * <p>Set up a worker pool to handle events from the ring buffer. The worker pool will only process events * after every {@link EventProcessor} in this group has processed the event. Each event will be processed * by one of the work handler instances.</p> * * <p>This method is generally used as part of a chain. For example if the handler <code>A</code> must * process events before the worker pool with handlers <code>B, C</code>:</p> * * <pre><code>dw.handleEventsWith(A).thenHandleEventsWithWorkerPool(B, C);</code></pre> * * @param handlers the work handlers that will process events. Each work handler instance will provide an extra thread in the worker pool. * @return a {@link EventHandlerGroup} that can be used to set up a event processor barrier over the created event processors. */ @SafeVarargs public final EventHandlerGroup<T> thenHandleEventsWithWorkerPool(final WorkHandler<? super T>... handlers) { return handleEventsWithWorkerPool(handlers); }
/** * <p>Set up a worker pool to handle events from the ring buffer. The worker pool will only process events * after every {@link EventProcessor} in this group has processed the event. Each event will be processed * by one of the work handler instances.</p> * * <p>This method is generally used as part of a chain. For example if the handler <code>A</code> must * process events before the worker pool with handlers <code>B, C</code>:</p> * * <pre><code>dw.handleEventsWith(A).thenHandleEventsWithWorkerPool(B, C);</code></pre> * * @param handlers the work handlers that will process events. Each work handler instance will provide an extra thread in the worker pool. * @return a {@link EventHandlerGroup} that can be used to set up a event processor barrier over the created event processors. */ @SafeVarargs public final EventHandlerGroup<T> thenHandleEventsWithWorkerPool(final WorkHandler<? super T>... handlers) { return handleEventsWithWorkerPool(handlers); }
handlers[i] = rawMessageEncoderHandlerProvider.get(); disruptor.handleEventsWithWorkerPool(handlers).then(spoolingMessageHandlerProvider.get()); } else { LOG.info("Message journal is disabled.");
/** * <p>Set up batch handlers to consume events from the ring buffer. These handlers will only process events * after every {@link EventProcessor} in this group has processed the event.</p> * * <p>This method is generally used as part of a chain. For example if the handler <code>A</code> must * process events before handler <code>B</code>:</p> * * <pre><code>dw.handleEventsWith(A).then(B);</code></pre> * * @param handlers the batch handlers that will process events. * @return a {@link EventHandlerGroup} that can be used to set up a event processor barrier over the created event processors. */ @SafeVarargs public final EventHandlerGroup<T> then(final EventHandler<? super T>... handlers) { return handleEventsWith(handlers); }
/** * <p>Create a group of event handlers to be used as a dependency. * For example if the handler <code>A</code> must process events before handler <code>B</code>:</p> * * <pre><code>dw.after(A).handleEventsWith(B);</code></pre> * * @param handlers the event handlers, previously set up with {@link #handleEventsWith(com.lmax.disruptor.EventHandler[])}, * that will form the barrier for subsequent handlers or processors. * @return an {@link EventHandlerGroup} that can be used to setup a dependency barrier over the specified event handlers. */ @SafeVarargs @SuppressWarnings("varargs") public final EventHandlerGroup<T> after(final EventHandler<T>... handlers) { final Sequence[] sequences = new Sequence[handlers.length]; for (int i = 0, handlersLength = handlers.length; i < handlersLength; i++) { sequences[i] = consumerRepository.getSequenceFor(handlers[i]); } return new EventHandlerGroup<>(this, consumerRepository, sequences); }
/** * Set up a worker pool to handle events from the ring buffer. The worker pool will only process events * after every {@link EventProcessor} in this group has processed the event. Each event will be processed * by one of the work handler instances. * <p> * <p>This method is generally used as part of a chain. For example if the handler <code>A</code> must * process events before the worker pool with handlers <code>B, C</code>:</p> * <p> * <pre><code>dw.handleEventsWith(A).thenHandleEventsWithWorkerPool(B, C);</code></pre> * * @param handlers the work handlers that will process events. Each work handler instance will provide an extra thread in the worker pool. * @return a {@link EventHandlerGroup} that can be used to set up a event processor barrier over the created event processors. */ public EventHandlerGroup<T> thenHandleEventsWithWorkerPool(final WorkHandler<? super T>... handlers) { return handleEventsWithWorkerPool(handlers); }
@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(expected = IllegalArgumentException.class) public void shouldThrowExceptionIfHandlerIsNotAlreadyConsuming() throws Exception { disruptor.after(createDelayedEventHandler()).handleEventsWith(createDelayedEventHandler()); }
/** * Create a new event handler group that combines the handlers in this group with <code>processors</code>. * * @param processors the processors to combine. * @return a new EventHandlerGroup combining the existing and new processors into a single dependency group. */ public EventHandlerGroup<T> and(final EventProcessor... processors) { Sequence[] combinedSequences = new Sequence[sequences.length + processors.length]; for (int i = 0; i < processors.length; i++) { consumerRepository.add(processors[i]); combinedSequences[i] = processors[i].getSequence(); } System.arraycopy(sequences, 0, combinedSequences, processors.length, sequences.length); return new EventHandlerGroup<>(disruptor, consumerRepository, combinedSequences); }
/** * Set up a worker pool to handle events from the ring buffer. The worker pool will only process events * after every {@link EventProcessor} in this group has processed the event. Each event will be processed * by one of the work handler instances. * * <p>This method is generally used as part of a chain. For example if the handler <code>A</code> must * process events before the worker pool with handlers <code>B, C</code>:</p> * * <pre><code>dw.handleEventsWith(A).thenHandleEventsWithWorkerPool(B, C);</code></pre> * * @param handlers the work handlers that will process events. Each work handler instance will provide an extra thread in the worker pool. * @return a {@link EventHandlerGroup} that can be used to set up a event processor barrier over the created event processors. */ public EventHandlerGroup<T> thenHandleEventsWithWorkerPool(final WorkHandler<? super T>... handlers) { return handleEventsWithWorkerPool(handlers); }
@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); }
/** * 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)); }