@Test public void shouldWaitForWorkCompleteWhereCompleteWorkThresholdIsBehind() throws Exception { long expectedNumberMessages = 10; fillRingBuffer(expectedNumberMessages); final StubEventProcessor[] eventProcessors = new StubEventProcessor[3]; for (int i = 0, size = eventProcessors.length; i < size; i++) { eventProcessors[i] = new StubEventProcessor(); eventProcessors[i].setSequence(expectedNumberMessages - 2); } final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(Util.getSequencesFor(eventProcessors)); Runnable runnable = new Runnable() { public void run() { for (StubEventProcessor stubWorker : eventProcessors) { stubWorker.setSequence(stubWorker.getSequence().get() + 1L); } } }; Thread thread = new Thread(runnable); thread.start(); thread.join(); long expectedWorkSequence = expectedNumberMessages - 1; long completedWorkSequence = sequenceBarrier.waitFor(expectedWorkSequence); assertTrue(completedWorkSequence >= expectedWorkSequence); }
@Test public void shouldWaitForWorkCompleteWhereAllWorkersAreBlockedOnRingBuffer() throws Exception { long expectedNumberMessages = 10; fillRingBuffer(expectedNumberMessages); final StubEventProcessor[] workers = new StubEventProcessor[3]; for (int i = 0, size = workers.length; i < size; i++) { workers[i] = new StubEventProcessor(); workers[i].setSequence(expectedNumberMessages - 1); } final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(Util.getSequencesFor(workers)); Runnable runnable = new Runnable() { public void run() { long sequence = ringBuffer.next(); StubEvent event = ringBuffer.getPreallocated(sequence); event.setValue((int) sequence); ringBuffer.publish(sequence); for (StubEventProcessor stubWorker : workers) { stubWorker.setSequence(sequence); } } }; new Thread(runnable).start(); long expectedWorkSequence = expectedNumberMessages; long completedWorkSequence = sequenceBarrier.waitFor(expectedNumberMessages); assertTrue(completedWorkSequence >= expectedWorkSequence); }
@Test public void shouldInterruptDuringBusySpin() throws Exception { final long expectedNumberMessages = 10; fillRingBuffer(expectedNumberMessages); final CountDownLatch latch = new CountDownLatch(3); final Sequence sequence1 = new CountDownLatchSequence(8L, latch); final Sequence sequence2 = new CountDownLatchSequence(8L, latch); final Sequence sequence3 = new CountDownLatchSequence(8L, latch); context.checking( new Expectations() { { one(eventProcessor1).getSequence(); will(returnValue(sequence1)); one(eventProcessor2).getSequence(); will(returnValue(sequence2)); one(eventProcessor3).getSequence(); will(returnValue(sequence3)); } }); final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier( Util.getSequencesFor(eventProcessor1, eventProcessor2, eventProcessor3)); final boolean[] alerted = {false}; Thread t = new Thread( new Runnable() { public void run() { try { sequenceBarrier.waitFor(expectedNumberMessages - 1); } catch (AlertException e) { alerted[0] = true; } catch (InterruptedException e) { // don't care } } }); t.start(); latch.await(3, TimeUnit.SECONDS); sequenceBarrier.alert(); t.join(); assertTrue("Thread was not interrupted", alerted[0]); }