@Test public void shouldReportProgressByUpdatingSequenceViaCallback() throws Exception { final RingBuffer<StubEvent> ringBuffer = createMultiProducer(StubEvent.EVENT_FACTORY, 16); final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(); final SequenceReportingEventHandler<StubEvent> handler = new TestSequenceReportingEventHandler(); final BatchEventProcessor<StubEvent> batchEventProcessor = new BatchEventProcessor<StubEvent>( ringBuffer, sequenceBarrier, handler); ringBuffer.addGatingSequences(batchEventProcessor.getSequence()); Thread thread = new Thread(batchEventProcessor); thread.setDaemon(true); thread.start(); assertEquals(-1L, batchEventProcessor.getSequence().get()); ringBuffer.publish(ringBuffer.next()); callbackLatch.await(); assertEquals(0L, batchEventProcessor.getSequence().get()); onEndOfBatchLatch.countDown(); assertEquals(0L, batchEventProcessor.getSequence().get()); batchEventProcessor.halt(); thread.join(); }
new BatchEventProcessor<StubEvent>(ringBuffer, ringBuffer.newBarrier(processor1.getSequence()), handler2); ringBuffer.addGatingSequences(processor1.getSequence(), processor2.getSequence()); ringBuffer.removeGatingSequence(processor2.getSequence());
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<>(ringBuffer, barrier, eventHandler); if (exceptionHandler != null) { batchEventProcessor.setExceptionHandler(exceptionHandler); } consumerRepository.add(batchEventProcessor, eventHandler, barrier); processorSequences[i] = batchEventProcessor.getSequence(); } updateGatingSequencesForNextInChain(barrierSequences, processorSequences); return new EventHandlerGroup<>(this, consumerRepository, processorSequences); }
@Test public void shouldCallExceptionHandlerOnUncaughtException() throws Exception { CountDownLatch exceptionLatch = new CountDownLatch(1); LatchExceptionHandler latchExceptionHandler = new LatchExceptionHandler(exceptionLatch); final BatchEventProcessor<StubEvent> batchEventProcessor = new BatchEventProcessor<StubEvent>( ringBuffer, sequenceBarrier, new ExceptionEventHandler()); ringBuffer.addGatingSequences(batchEventProcessor.getSequence()); batchEventProcessor.setExceptionHandler(latchExceptionHandler); Thread thread = new Thread(batchEventProcessor); thread.start(); ringBuffer.publish(ringBuffer.next()); assertTrue(exceptionLatch.await(2, TimeUnit.SECONDS)); batchEventProcessor.halt(); thread.join(); }
new SimpleParserStage(logContext)); simpleParserStage.setExceptionHandler(exceptionHandler); disruptorMsgBuffer.addGatingSequences(simpleParserStage.getSequence()); SequenceBarrier dmlParserSequenceBarrier = disruptorMsgBuffer.newBarrier(simpleParserStage.getSequence()); WorkHandler<MessageEvent>[] workHandlers = new DmlParserStage[parserThreadCount]; for (int i = 0; i < parserThreadCount; i++) { new SinkStoreStage()); sinkStoreStage.setExceptionHandler(exceptionHandler); disruptorMsgBuffer.addGatingSequences(sinkStoreStage.getSequence());
@Test public void shouldCallMethodsInLifecycleOrderForBatch() throws Exception { CountDownLatch eventLatch = new CountDownLatch(3); LatchEventHandler eventHandler = new LatchEventHandler(eventLatch); final BatchEventProcessor<StubEvent> batchEventProcessor = new BatchEventProcessor<StubEvent>( ringBuffer, sequenceBarrier, eventHandler); ringBuffer.addGatingSequences(batchEventProcessor.getSequence()); ringBuffer.publish(ringBuffer.next()); ringBuffer.publish(ringBuffer.next()); ringBuffer.publish(ringBuffer.next()); Thread thread = new Thread(batchEventProcessor); thread.start(); assertTrue(eventLatch.await(2, TimeUnit.SECONDS)); batchEventProcessor.halt(); thread.join(); }
@Test public void shouldAddEventProcessorsAfterPublishing() throws Exception { RingBuffer<TestEvent> rb = disruptor.getRingBuffer(); BatchEventProcessor<TestEvent> b1 = new BatchEventProcessor<TestEvent>( rb, rb.newBarrier(), new SleepingEventHandler()); BatchEventProcessor<TestEvent> b2 = new BatchEventProcessor<TestEvent>( rb, rb.newBarrier(b1.getSequence()), new SleepingEventHandler()); BatchEventProcessor<TestEvent> b3 = new BatchEventProcessor<TestEvent>( rb, rb.newBarrier(b2.getSequence()), new SleepingEventHandler()); assertThat(b1.getSequence().get(), is(-1L)); assertThat(b2.getSequence().get(), is(-1L)); assertThat(b3.getSequence().get(), is(-1L)); 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.handleEventsWith(b1, b2, b3); assertThat(b1.getSequence().get(), is(5L)); assertThat(b2.getSequence().get(), is(5L)); assertThat(b3.getSequence().get(), is(5L)); }
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<>(ringBuffer, barrier, eventHandler); if (exceptionHandler != null) { batchEventProcessor.setExceptionHandler(exceptionHandler); } consumerRepository.add(batchEventProcessor, eventHandler, barrier); processorSequences[i] = batchEventProcessor.getSequence(); } updateGatingSequencesForNextInChain(barrierSequences, processorSequences); return new EventHandlerGroup<>(this, consumerRepository, processorSequences); }
public void subscribe(URI uri, ChannelConnection connection) { if (ringBuffer == null) { subscribers.put(uri, connection); } else { // ring buffer already started, add dynamically ChannelEventHandler handler = new ChannelEventHandler(connection); SequenceBarrier barrier = ringBuffer.newBarrier(); BatchEventProcessor<RingBufferEvent> processor = new BatchEventProcessor<RingBufferEvent>(ringBuffer, barrier, handler); Sequence sequence = processor.getSequence(); sequenceGroup.addWhileRunning(ringBuffer, sequence); executorService.execute(processor); sequences.put(uri, sequence); subscribers.put(uri, connection); } }
public void subscribe(URI uri, ChannelConnection connection) { if (ringBuffer == null) { subscribers.put(uri, connection); } else { // ring buffer already started, add dynamically boolean channelEvent = EventHandlerHelper.isChannelEvent(connection); ChannelEventHandler handler = new ChannelEventHandler(connection, channelEvent); SequenceBarrier barrier = ringBuffer.newBarrier(); BatchEventProcessor<RingBufferEvent> processor = new BatchEventProcessor<>(ringBuffer, barrier, handler); Sequence sequence = processor.getSequence(); sequenceGroup.addWhileRunning(ringBuffer, sequence); executorService.execute(processor); sequences.put(uri, sequence); subscribers.put(uri, connection); } }
@Inject ReplyProcessorImpl(MetricsRegistry metrics, Panicker panicker) { replyRing = RingBuffer.<ReplyEvent>createMultiProducer(ReplyEvent.EVENT_FACTORY, 1<<12, new BusySpinWaitStrategy()); SequenceBarrier replySequenceBarrier = replyRing.newBarrier(); BatchEventProcessor<ReplyEvent> replyProcessor = new BatchEventProcessor<ReplyEvent>( replyRing, replySequenceBarrier, this); replyProcessor.setExceptionHandler(new FatalExceptionHandler(panicker)); replyRing.addGatingSequences(replyProcessor.getSequence()); ExecutorService replyExec = Executors.newSingleThreadExecutor( new ThreadFactoryBuilder().setNameFormat("reply-%d").build()); replyExec.submit(replyProcessor); abortMeter = metrics.meter(name("tso", "aborts")); commitMeter = metrics.meter(name("tso", "commits")); timestampMeter = metrics.meter(name("tso", "timestampAllocation")); }
@Inject ReplyProcessorImpl(MetricsRegistry metrics, Panicker panicker, ObjectPool<Batch> batchPool) { this.batchPool = batchPool; this.nextIDToHandle.set(0); this.replyRing = RingBuffer.createMultiProducer(ReplyBatchEvent.EVENT_FACTORY, 1 << 12, new BusySpinWaitStrategy()); SequenceBarrier replySequenceBarrier = replyRing.newBarrier(); BatchEventProcessor<ReplyBatchEvent> replyProcessor = new BatchEventProcessor<>(replyRing, replySequenceBarrier, this); replyProcessor.setExceptionHandler(new FatalExceptionHandler(panicker)); replyRing.addGatingSequences(replyProcessor.getSequence()); ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("reply-%d").build(); ExecutorService replyExec = Executors.newSingleThreadExecutor(threadFactory); replyExec.submit(replyProcessor); this.futureEvents = new PriorityQueue<>(10, new Comparator<ReplyBatchEvent>() { public int compare(ReplyBatchEvent replyBatchEvent1, ReplyBatchEvent replyBatchEvent2) { return Long.compare(replyBatchEvent1.getBatchSequence(), replyBatchEvent2.getBatchSequence()); } }); this.abortMeter = metrics.meter(name("tso", "aborts")); this.commitMeter = metrics.meter(name("tso", "commits")); this.timestampMeter = metrics.meter(name("tso", "timestampAllocation")); }
@Inject RetryProcessorImpl(MetricsRegistry metrics, CommitTable commitTable, ReplyProcessor replyProc, Panicker panicker) throws InterruptedException, ExecutionException { this.commitTableClient = commitTable.getClient().get(); this.writer = commitTable.getWriter().get(); this.replyProc = replyProc; WaitStrategy strategy = new YieldingWaitStrategy(); retryRing = RingBuffer.<RetryEvent>createSingleProducer( RetryEvent.EVENT_FACTORY, 1<<12, strategy); SequenceBarrier retrySequenceBarrier = retryRing.newBarrier(); BatchEventProcessor<RetryEvent> retryProcessor = new BatchEventProcessor<RetryEvent>( retryRing, retrySequenceBarrier, this); retryProcessor.setExceptionHandler(new FatalExceptionHandler(panicker)); retryRing.addGatingSequences(retryProcessor.getSequence()); ExecutorService retryExec = Executors.newSingleThreadExecutor( new ThreadFactoryBuilder().setNameFormat("retry-%d").build()); retryExec.submit(retryProcessor); // Metrics retriesMeter = metrics.meter(name("tso", "retries")); }
@Inject RetryProcessorImpl(MetricsRegistry metrics, CommitTable commitTable, ReplyProcessor replyProc, Panicker panicker, ObjectPool<Batch> batchPool) throws InterruptedException, ExecutionException, IOException { this.commitTableClient = commitTable.getClient(); this.replyProc = replyProc; this.batchPool = batchPool; retryRing = RingBuffer.createSingleProducer(RetryEvent.EVENT_FACTORY, 1 << 12, new YieldingWaitStrategy()); SequenceBarrier retrySequenceBarrier = retryRing.newBarrier(); BatchEventProcessor<RetryEvent> retryProcessor = new BatchEventProcessor<>(retryRing, retrySequenceBarrier, this); retryProcessor.setExceptionHandler(new FatalExceptionHandler(panicker)); retryRing.addGatingSequences(retryProcessor.getSequence()); ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("retry-%d").build(); ExecutorService retryExec = Executors.newSingleThreadExecutor(threadFactory); retryExec.submit(retryProcessor); // Metrics configuration retriesMeter = metrics.meter(name("tso", "retries")); }
@Inject RequestProcessorImpl(MetricsRegistry metrics, TimestampOracle timestampOracle, PersistenceProcessor persistProc, Panicker panicker, TSOServerConfig config) throws IOException { this.metrics = metrics; this.persistProc = persistProc; this.timestampOracle = timestampOracle; this.hashmap = new CommitHashMap(config.getMaxItems()); final TimeoutBlockingWaitStrategy timeoutStrategy = new TimeoutBlockingWaitStrategy(config.getBatchPersistTimeoutInMs(), TimeUnit.MILLISECONDS); // Set up the disruptor thread requestRing = RingBuffer.createMultiProducer(RequestEvent.EVENT_FACTORY, 1 << 12, timeoutStrategy); SequenceBarrier requestSequenceBarrier = requestRing.newBarrier(); BatchEventProcessor<RequestEvent> requestProcessor = new BatchEventProcessor<>(requestRing, requestSequenceBarrier, this); requestRing.addGatingSequences(requestProcessor.getSequence()); requestProcessor.setExceptionHandler(new FatalExceptionHandler(panicker)); ExecutorService requestExec = Executors.newSingleThreadExecutor( new ThreadFactoryBuilder().setNameFormat("request-%d").build()); // Each processor runs on a separate thread requestExec.submit(requestProcessor); }
@Inject RequestProcessorImpl(MetricsRegistry metrics, TimestampOracle timestampOracle, PersistenceProcessor persistProc, Panicker panicker, TSOServerConfig config) { this.persistProc = persistProc; this.timestampOracle = timestampOracle; this.lowWatermark = timestampOracle.getLast(); persistProc.persistLowWatermark(lowWatermark); this.hashmap = new CommitHashMap(config.getMaxItems(), lowWatermark); // Set up the disruptor thread requestRing = RingBuffer.<RequestEvent>createMultiProducer(RequestEvent.EVENT_FACTORY, 1<<12, new BusySpinWaitStrategy()); SequenceBarrier requestSequenceBarrier = requestRing.newBarrier(); BatchEventProcessor<RequestEvent> requestProcessor = new BatchEventProcessor<RequestEvent>(requestRing, requestSequenceBarrier, this); requestRing.addGatingSequences(requestProcessor.getSequence()); requestProcessor.setExceptionHandler(new FatalExceptionHandler(panicker)); ExecutorService requestExec = Executors.newSingleThreadExecutor( new ThreadFactoryBuilder().setNameFormat("request-%d").build()); // Each processor runs on a separate thread requestExec.submit(requestProcessor); }
persistSequenceBarrier, this); persistRing.addGatingSequences(persistProcessor.getSequence()); persistProcessor.setExceptionHandler(new FatalExceptionHandler(panicker));
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<>(ringBuffer, barrier, eventHandler); if (exceptionHandler != null) { batchEventProcessor.setExceptionHandler(exceptionHandler); } consumerRepository.add(batchEventProcessor, eventHandler, barrier); processorSequences[i] = batchEventProcessor.getSequence(); } updateGatingSequencesForNextInChain(barrierSequences, processorSequences); return new EventHandlerGroup<>(this, consumerRepository, processorSequences); }
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); }
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); }