@Override public void release() { sequence.set(Long.MAX_VALUE); } };
/** * @see Sequencer#claim(long) */ @Override public void claim(long sequence) { cursor.set(sequence); }
/** * Set all {@link Sequence}s in the group to a given value. * * @param value to set the group of sequences to. */ @Override public void set(final long value) { final Sequence[] sequences = this.sequences; for (Sequence sequence : sequences) { sequence.set(value); } }
/** * @see Sequencer#claim(long) */ @Override public void claim(long sequence) { cursor.set(sequence); }
/** * @see Sequencer#publish(long) */ @Override public void publish(long sequence) { cursor.set(sequence); waitStrategy.signalAllWhenBlocking(); }
public void setSequence(long sequence) { this.sequence.set(sequence); }
/** * @see Sequencer#publish(long) */ @Override public void publish(long sequence) { cursor.set(sequence); waitStrategy.signalAllWhenBlocking(); }
/** * Start the worker pool processing events in sequence. * * @param executor providing threads for running the workers. * @return the {@link RingBuffer} used for the work queue. * @throws IllegalStateException if the pool has already been started and not halted yet */ public RingBuffer<T> start(final Executor executor) { if (!started.compareAndSet(false, true)) { throw new IllegalStateException("WorkerPool has already been started and cannot be restarted until halted."); } final long cursor = ringBuffer.getCursor(); workSequence.set(cursor); for (WorkProcessor<?> processor : workProcessors) { processor.getSequence().set(cursor); executor.execute(processor); } return ringBuffer; }
@Override public void onEvent(final StubEvent event, final long sequence, final boolean endOfBatch) throws Exception { sequenceCallback.set(sequence); callbackLatch.countDown(); if (endOfBatch) { onEndOfBatchLatch.await(); } } }
private boolean hasAvailableCapacity(Sequence[] gatingSequences, final int requiredCapacity, long cursorValue) { long wrapPoint = (cursorValue + requiredCapacity) - bufferSize; long cachedGatingSequence = gatingSequenceCache.get(); if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue) { long minSequence = Util.getMinimumSequence(gatingSequences, cursorValue); gatingSequenceCache.set(minSequence); if (wrapPoint > minSequence) { return false; } } return true; }
static <T> void addSequences( final T holder, final AtomicReferenceFieldUpdater<T, Sequence[]> updater, final Cursored cursor, final Sequence... sequencesToAdd) { long cursorSequence; Sequence[] updatedSequences; Sequence[] currentSequences; do { currentSequences = updater.get(holder); updatedSequences = copyOf(currentSequences, currentSequences.length + sequencesToAdd.length); cursorSequence = cursor.getCursor(); int index = currentSequences.length; for (Sequence sequence : sequencesToAdd) { sequence.set(cursorSequence); updatedSequences[index++] = sequence; } } while (!updater.compareAndSet(holder, currentSequences, updatedSequences)); cursorSequence = cursor.getCursor(); for (Sequence sequence : sequencesToAdd) { sequence.set(cursorSequence); } }
private boolean hasAvailableCapacity(Sequence[] gatingSequences, final int requiredCapacity, long cursorValue) { long wrapPoint = (cursorValue + requiredCapacity) - bufferSize; long cachedGatingSequence = gatingSequenceCache.get(); if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue) { long minSequence = Util.getMinimumSequence(gatingSequences, cursorValue); gatingSequenceCache.set(minSequence); if (wrapPoint > minSequence) { return false; } } return true; }
private synchronized List<Object> getConsumeBatch() throws AlertException, InterruptedException, TimeoutException { long endCursor = getAvailableConsumeCursor(); long currCursor = _consumer.get(); long eventNumber = endCursor - currCursor; List<Object> batch = new ArrayList<>((int) eventNumber); for (long curr = currCursor + 1; curr <= endCursor; curr++) { try { MutableObject mo = _buffer.get(curr); Object o = mo.o; mo.setObject(null); batch.add(o); } catch (Exception e) { LOG.error(e.getMessage(), e); throw new RuntimeException(e); } } _consumer.set(endCursor); return batch; }
public void consumeBatchToCursor(EventHandler<Object> handler) throws AlertException, InterruptedException, TimeoutException { long endCursor = getAvailableConsumeCursor(); long curr = _consumer.get() + 1; for (; curr <= endCursor; curr++) { try { MutableObject mo = _buffer.get(curr); Object o = mo.o; mo.setObject(null); handler.onEvent(o, curr, curr == endCursor); } catch (InterruptedException e) { LOG.error(e.getMessage(), e); return; } catch (Exception e) { LOG.error(e.getMessage(), e); throw new RuntimeException(e); } } // TODO: only set this if the consumer cursor has changed? _consumer.set(endCursor); }
@Override public void run() { if (!running.compareAndSet(false, true)) { throw new IllegalStateException("Already running"); } try { sequenceBarrier.waitFor(0L); } catch (Exception ex) { throw new RuntimeException(ex); } sequence.set(sequence.get() + 1L); } }
@Test public void shouldReturnMinimumOf2Sequences() throws Exception { Sequence sequence1 = new Sequence(34); Sequence sequnece2 = new Sequence(47); Sequence group = new FixedSequenceGroup(new Sequence[]{sequence1, sequnece2}); assertThat(group.get(), is(34L)); sequence1.set(35); assertThat(group.get(), is(35L)); sequence1.set(48); assertThat(group.get(), is(47L)); } }
sequence.set(processedSequence);
@Test public void shouldHoldUpPublisherWhenBufferIsFull() throws InterruptedException { sequencer.addGatingSequences(gatingSequence); long sequence = sequencer.next(BUFFER_SIZE); sequencer.publish(sequence - (BUFFER_SIZE - 1), sequence); final CountDownLatch waitingLatch = new CountDownLatch(1); final CountDownLatch doneLatch = new CountDownLatch(1); final long expectedFullSequence = Sequencer.INITIAL_CURSOR_VALUE + sequencer.getBufferSize(); assertThat(sequencer.getCursor(), is(expectedFullSequence)); executor.submit( new Runnable() { @Override public void run() { waitingLatch.countDown(); long next = sequencer.next(); sequencer.publish(next); doneLatch.countDown(); } }); waitingLatch.await(); assertThat(sequencer.getCursor(), is(expectedFullSequence)); gatingSequence.set(Sequencer.INITIAL_CURSOR_VALUE + 1L); doneLatch.await(); assertThat(sequencer.getCursor(), is(expectedFullSequence + 1L)); }
@Test public void shouldAddAndRemoveSequences() throws Exception { RingBuffer<Object[]> ringBuffer = RingBuffer.createSingleProducer(new ArrayFactory(1), 16); Sequence sequenceThree = new Sequence(-1); Sequence sequenceSeven = new Sequence(-1); ringBuffer.addGatingSequences(sequenceThree, sequenceSeven); for (int i = 0; i < 10; i++) { ringBuffer.publish(ringBuffer.next()); } sequenceThree.set(3); sequenceSeven.set(7); assertThat(ringBuffer.getMinimumGatingSequence(), is(3L)); assertTrue(ringBuffer.removeGatingSequence(sequenceThree)); assertThat(ringBuffer.getMinimumGatingSequence(), is(7L)); }
@SuppressWarnings("deprecation") private void assertHandleResetAndNotWrap(RingBuffer<StubEvent> rb) { Sequence sequence = new Sequence(); rb.addGatingSequences(sequence); for (int i = 0; i < 128; i++) { rb.publish(rb.next()); sequence.incrementAndGet(); } assertThat(rb.getCursor(), is(127L)); rb.resetTo(31); sequence.set(31); for (int i = 0; i < 4; i++) { rb.publish(rb.next()); } assertThat(rb.hasAvailableCapacity(1), is(false)); }