private void ensureTwoEventsProcessedAccordingToDependencies( final CountDownLatch countDownLatch, final DelayedEventHandler... dependencies) throws InterruptedException, BrokenBarrierException { publishEvent(); publishEvent(); for (DelayedEventHandler dependency : dependencies) { assertThatCountDownLatchEquals(countDownLatch, 2L); dependency.processEvent(); dependency.processEvent(); } assertThatCountDownLatchIsZero(countDownLatch); }
@Test public void shouldMakeEntriesAvailableToFirstHandlersImmediately() throws Exception { CountDownLatch countDownLatch = new CountDownLatch(2); EventHandler<TestEvent> eventHandler = new EventHandlerStub<TestEvent>(countDownLatch); disruptor.handleEventsWith(createDelayedEventHandler(), eventHandler); ensureTwoEventsProcessedAccordingToDependencies(countDownLatch); }
@Before public void setUp() throws Exception { createDisruptor(); }
@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 shouldSupportUsingWorkerPoolWithADependency() throws Exception { final TestWorkHandler workHandler1 = createTestWorkHandler(); final TestWorkHandler workHandler2 = createTestWorkHandler(); final DelayedEventHandler delayedEventHandler = createDelayedEventHandler(); disruptor.handleEventsWith(delayedEventHandler).thenHandleEventsWithWorkerPool(workHandler1, workHandler2); publishEvent(); publishEvent(); delayedEventHandler.processEvent(); delayedEventHandler.processEvent(); workHandler1.processEvent(); workHandler2.processEvent(); }
@Test public void shouldBeAbleToOverrideTheExceptionHandlerForAEventProcessor() throws Exception { final RuntimeException testException = new RuntimeException(); final ExceptionThrowingEventHandler eventHandler = new ExceptionThrowingEventHandler(testException); disruptor.handleEventsWith(eventHandler); AtomicReference<Throwable> reference = new AtomicReference<Throwable>(); StubExceptionHandler exceptionHandler = new StubExceptionHandler(reference); disruptor.handleExceptionsFor(eventHandler).with(exceptionHandler); publishEvent(); waitFor(reference); }
@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 shouldBlockProducerUntilAllEventProcessorsHaveAdvanced() throws Exception { final DelayedEventHandler delayedEventHandler = createDelayedEventHandler(); disruptor.handleEventsWith(delayedEventHandler); final RingBuffer<TestEvent> ringBuffer = disruptor.start(); delayedEventHandler.awaitStart(); final StubPublisher stubPublisher = new StubPublisher(ringBuffer); try { executor.newThread(stubPublisher).start(); assertProducerReaches(stubPublisher, 4, true); delayedEventHandler.processEvent(); delayedEventHandler.processEvent(); delayedEventHandler.processEvent(); delayedEventHandler.processEvent(); delayedEventHandler.processEvent(); assertProducerReaches(stubPublisher, 5, false); } finally { stubPublisher.halt(); } }
@Test public void shouldAllowEventHandlerWithSuperType() throws Exception { final CountDownLatch latch = new CountDownLatch(2); final EventHandler<Object> objectHandler = new EventHandlerStub<Object>(latch); disruptor.handleEventsWith(objectHandler); ensureTwoEventsProcessedAccordingToDependencies(latch); }
@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); }
@Test(expected = IllegalArgumentException.class) public void shouldThrowExceptionIfHandlerIsNotAlreadyConsuming() throws Exception { disruptor.after(createDelayedEventHandler()).handleEventsWith(createDelayedEventHandler()); }
@Test(timeout = 1000) public void shouldTrackRemainingCapacity() throws Exception { final long[] remainingCapacity = {-1}; //Given final EventHandler<TestEvent> eventHandler = new EventHandler<TestEvent>() { @Override public void onEvent(final TestEvent event, final long sequence, final boolean endOfBatch) throws Exception { remainingCapacity[0] = disruptor.getRingBuffer().remainingCapacity(); } }; disruptor.handleEventsWith(eventHandler); //When publishEvent(); //Then while (remainingCapacity[0] == -1) { Thread.sleep(100); } assertThat(remainingCapacity[0], is(ringBuffer.getBufferSize() - 1L)); assertThat(disruptor.getRingBuffer().remainingCapacity(), is(ringBuffer.getBufferSize() - 0L)); }
@Test public void shouldSupportUsingWorkerPoolAsDependencyAndProcessFirstEventAsSoonAsItIsAvailable() throws Exception { final TestWorkHandler workHandler1 = createTestWorkHandler(); final TestWorkHandler workHandler2 = createTestWorkHandler(); final DelayedEventHandler delayedEventHandler = createDelayedEventHandler(); disruptor.handleEventsWithWorkerPool(workHandler1, workHandler2).then(delayedEventHandler); publishEvent(); publishEvent(); workHandler1.processEvent(); delayedEventHandler.processEvent(); workHandler2.processEvent(); delayedEventHandler.processEvent(); }
@Test public void shouldSupportSpecifyingADefaultExceptionHandlerForEventProcessors() throws Exception { AtomicReference<Throwable> eventHandled = new AtomicReference<Throwable>(); ExceptionHandler exceptionHandler = new StubExceptionHandler(eventHandled); RuntimeException testException = new RuntimeException(); ExceptionThrowingEventHandler handler = new ExceptionThrowingEventHandler(testException); disruptor.setDefaultExceptionHandler(exceptionHandler); disruptor.handleEventsWith(handler); publishEvent(); final Throwable actualException = waitFor(eventHandled); assertSame(testException, actualException); }
@Test public void shouldMakeEntriesAvailableToFirstCustomProcessorsImmediately() throws Exception { final CountDownLatch countDownLatch = new CountDownLatch(2); final EventHandler<TestEvent> eventHandler = new EventHandlerStub<TestEvent>(countDownLatch); disruptor.handleEventsWith( new EventProcessorFactory<TestEvent>() { @Override public EventProcessor createEventProcessor( final RingBuffer<TestEvent> ringBuffer, final Sequence[] barrierSequences) { assertEquals("Should not have had any barrier sequences", 0, barrierSequences.length); return new BatchEventProcessor<TestEvent>( disruptor.getRingBuffer(), ringBuffer.newBarrier( barrierSequences), eventHandler); } }); ensureTwoEventsProcessedAccordingToDependencies(countDownLatch); }
@Test public void shouldSetSequenceForWorkProcessorIfAddedAfterPublish() throws Exception { RingBuffer<TestEvent> rb = disruptor.getRingBuffer(); TestWorkHandler wh1 = createTestWorkHandler(); TestWorkHandler wh2 = createTestWorkHandler(); TestWorkHandler wh3 = createTestWorkHandler(); rb.publish(rb.next()); rb.publish(rb.next()); rb.publish(rb.next()); rb.publish(rb.next()); rb.publish(rb.next()); rb.publish(rb.next()); disruptor.handleEventsWithWorkerPool(wh1, wh2, wh3); assertThat(disruptor.getRingBuffer().getMinimumGatingSequence(), is(5L)); }
@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); }
@Test public void shouldSupportUsingWorkerPoolAsDependency() throws Exception { final TestWorkHandler workHandler1 = createTestWorkHandler(); final TestWorkHandler workHandler2 = createTestWorkHandler(); final DelayedEventHandler delayedEventHandler = createDelayedEventHandler(); disruptor.handleEventsWithWorkerPool(workHandler1, workHandler2).then(delayedEventHandler); publishEvent(); publishEvent(); assertThat(disruptor.getBarrierFor(delayedEventHandler).getCursor(), equalTo(-1L)); workHandler2.processEvent(); workHandler1.processEvent(); delayedEventHandler.processEvent(); }
@Test public void shouldApplyDefaultExceptionHandlerToExistingEventProcessors() throws Exception { AtomicReference<Throwable> eventHandled = new AtomicReference<Throwable>(); ExceptionHandler exceptionHandler = new StubExceptionHandler(eventHandled); RuntimeException testException = new RuntimeException(); ExceptionThrowingEventHandler handler = new ExceptionThrowingEventHandler(testException); disruptor.handleEventsWith(handler); disruptor.setDefaultExceptionHandler(exceptionHandler); publishEvent(); final Throwable actualException = waitFor(eventHandled); assertSame(testException, actualException); }
private void createDisruptor() { executor = new StubThreadFactory(); createDisruptor(executor); }