/** * 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); }
/** * Specify the {@link ExceptionHandler} to use with the event handler. * * @param exceptionHandler the exception handler to use. */ @SuppressWarnings("unchecked") public void with(ExceptionHandler<? super T> exceptionHandler) { final EventProcessor eventProcessor = consumerRepository.getEventProcessorFor(eventHandler); if (eventProcessor instanceof BatchEventProcessor) { ((BatchEventProcessor<T>) eventProcessor).setExceptionHandler(exceptionHandler); consumerRepository.getBarrierFor(eventHandler).alert(); } else { throw new RuntimeException( "EventProcessor: " + eventProcessor + " is not a BatchEventProcessor " + "and does not support exception handlers"); } } }
@Test public void shouldGetLastEventProcessorsInChain() throws Exception { consumerRepository.add(eventProcessor1, handler1, barrier1); consumerRepository.add(eventProcessor2, handler2, barrier2); consumerRepository.unMarkEventProcessorsAsEndOfChain(eventProcessor2.getSequence()); final Sequence[] lastEventProcessorsInChain = consumerRepository.getLastSequenceInChain(true); assertThat(lastEventProcessorsInChain.length, equalTo(1)); assertThat(lastEventProcessorsInChain[0], sameInstance(eventProcessor1.getSequence())); }
@Test public void shouldRetrieveEventProcessorForHandler() throws Exception { consumerRepository.add(eventProcessor1, handler1, barrier1); assertThat(consumerRepository.getEventProcessorFor(handler1), sameInstance(eventProcessor1)); }
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(); }
EventHandlerGroup<T> createEventProcessors(final Sequence[] barrierSequences, final EventHandler<? super T>[] eventHandlers) { checkNotStarted(); final Sequence[] processorSequences = new Sequence[eventHandlers.length]; final SequenceBarrier barrier = ringBuffer.newBarrier(barrierSequences); for (int i = 0, eventHandlersLength = eventHandlers.length; i < eventHandlersLength; i++) { final EventHandler<? super T> eventHandler = eventHandlers[i]; final BatchEventProcessor<T> batchEventProcessor = new BatchEventProcessor<T>(ringBuffer, barrier, eventHandler); if (exceptionHandler != null) { batchEventProcessor.setExceptionHandler(exceptionHandler); } consumerRepository.add(batchEventProcessor, eventHandler, barrier); processorSequences[i] = batchEventProcessor.getSequence(); } if (processorSequences.length > 0) { consumerRepository.unMarkEventProcessorsAsEndOfChain(barrierSequences); } return new EventHandlerGroup<T>(this, consumerRepository, processorSequences); }
@Test public void shouldGetBarrierByHandler() throws Exception { consumerRepository.add(eventProcessor1, handler1, barrier1); assertThat(consumerRepository.getBarrierFor(handler1), sameInstance(barrier1)); }
/** * Confirms if all messages have been consumed by all event processors */ private boolean hasBacklog() { final long cursor = ringBuffer.getCursor(); for (final Sequence consumer : consumerRepository.getLastSequenceInChain(false)) { if (cursor > consumer.get()) { return true; } } return false; }
/** * 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); }
public Sequence getSequenceFor(final EventHandler<T> handler) { return getEventProcessorFor(handler).getSequence(); }
/** * Gets the sequence value for the specified event handlers. * * @param b1 eventHandler to get the sequence for. * @return eventHandler's sequence */ public long getSequenceValueFor(final EventHandler<T> b1) { return consumerRepository.getSequenceFor(b1).get(); }
private void updateGatingSequencesForNextInChain(final Sequence[] barrierSequences, final Sequence[] processorSequences) { if (processorSequences.length > 0) { ringBuffer.addGatingSequences(processorSequences); for (final Sequence barrierSequence : barrierSequences) { ringBuffer.removeGatingSequence(barrierSequence); } consumerRepository.unMarkEventProcessorsAsEndOfChain(barrierSequences); } }
public void unMarkEventProcessorsAsEndOfChain(final Sequence... barrierEventProcessors) { for (Sequence barrierEventProcessor : barrierEventProcessors) { getEventProcessorInfo(barrierEventProcessor).markAsUsedInBarrier(); } }
EventHandlerGroup<T> createEventProcessors( final Sequence[] barrierSequences, final EventHandler<? super T>[] eventHandlers) { checkNotStarted(); final Sequence[] processorSequences = new Sequence[eventHandlers.length]; final SequenceBarrier barrier = ringBuffer.newBarrier(barrierSequences); for (int i = 0, eventHandlersLength = eventHandlers.length; i < eventHandlersLength; i++) { final EventHandler<? super T> eventHandler = eventHandlers[i]; final BatchEventProcessor<T> batchEventProcessor = new BatchEventProcessor<T>(ringBuffer, barrier, eventHandler); if (exceptionHandler != null) { batchEventProcessor.setExceptionHandler(exceptionHandler); } consumerRepository.add(batchEventProcessor, eventHandler, barrier); processorSequences[i] = batchEventProcessor.getSequence(); } if (processorSequences.length > 0) { consumerRepository.unMarkEventProcessorsAsEndOfChain(barrierSequences); } return new EventHandlerGroup<T>(this, consumerRepository, processorSequences); }
/** * Confirms if all messages have been consumed by all event processors */ private boolean hasBacklog() { final long cursor = ringBuffer.getCursor(); for (final Sequence consumer : consumerRepository.getLastSequenceInChain(false)) { if (cursor > consumer.get()) { return true; } } return false; }
@Test public void shouldReturnNullForBarrierWhenHandlerIsNotRegistered() throws Exception { assertThat(consumerRepository.getBarrierFor(handler1), is(nullValue())); }
@Test(expected = IllegalArgumentException.class) public void shouldThrowExceptionWhenHandlerIsNotRegistered() throws Exception { consumerRepository.getEventProcessorFor(new SleepingEventHandler()); }
/** * <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); }
private void updateGatingSequencesForNextInChain(final Sequence[] barrierSequences, final Sequence[] processorSequences) { if (processorSequences.length > 0) { ringBuffer.addGatingSequences(processorSequences); for (final Sequence barrierSequence : barrierSequences) { ringBuffer.removeGatingSequence(barrierSequence); } consumerRepository.unMarkEventProcessorsAsEndOfChain(barrierSequences); } }
/** * 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)); }