/** * Tries to add (write) event to the batch, returns true, if successful. If fails, no subsequent attempts to add event * to this batch will succeed, the next batch should be taken. */ boolean tryAddEvent(byte[] event) { while (true) { long state = getState(); if (isSealed(state)) { return false; } int bufferWatermark = bufferWatermark(state); if (bufferWatermark == 0) { if (tryAddFirstEvent(event)) { return true; } } else if (newBufferWatermark(bufferWatermark, event) <= emitter.maxBufferWatermark) { if (tryAddNonFirstEvent(state, event)) { return true; } } else { seal(); return false; } } }
private void tryRecoverCurrentBatch(Integer failedBatchNumber) { log.info("Trying to recover currentBatch"); long nextBatchNumber = ConcurrentAwaitableCounter.nextCount(failedBatchNumber); byte[] newBuffer = acquireBuffer(); if (concurrentBatch.compareAndSet(failedBatchNumber, new Batch(this, newBuffer, nextBatchNumber))) { log.info("Successfully recovered currentBatch"); } else { // It's normal, a concurrent thread could succeed to recover first. buffersToReuse.add(newBuffer); } }
void awaitEmittingAllowed() { acquireShared(1); }
@Override public String toString() { long state = getState(); return "Batch{" + "batchNumber=" + batchNumber + ", bufferWatermark=" + bufferWatermark(state) + ", parties=" + parties(state) + ", isSealed=" + isSealed(state) + "}"; }
@Override protected long tryAcquireShared(long ignored) { return isEmittingAllowed(getState()) ? 1 : -1; }
int getSealedBufferWatermark() { long state = getState(); Preconditions.checkState(isSealed(state)); return bufferWatermark(state); }
long state = getState(); int parties = parties(state); if (parties == 0) { throw new IllegalMonitorStateException(); if (compareAndSetState(state, newState)) { return isEmittingAllowed(newState); long state = getState(); int parties = parties(state); if (parties == 0) { throw new IllegalMonitorStateException(); if (compareAndSetState(state, newState)) { if (!isSealed(state)) { log.debug("Unlocked and sealed batch [%d]", batchNumber); debugLogState("old state", state); debugLogState("new state", newState); emitter.onSealExclusive( this, return isEmittingAllowed(newState); long state = getState(); if (isSealed(state)) { if (compareAndSetState(state, newState)) { log.debug("Sealed batch [%d]", batchNumber);
/** * Returns the buffer offset at which the caller has reserved the ability to write `size` bytes exclusively, * or negative number, if the reservation attempt failed. */ private int tryReserveEventSizeAndLock(long state, int size) { Preconditions.checkArgument(size > 0); int bufferWatermark = bufferWatermark(state); while (true) { if (compareAndSetState(state, state + size + PARTY)) { return bufferWatermark; } state = getState(); if (isSealed(state)) { return -1; } bufferWatermark = bufferWatermark(state); int newBufferWatermark = bufferWatermark + size; Preconditions.checkState(newBufferWatermark > 0); if (newBufferWatermark > emitter.maxBufferWatermark) { return -1; } } }
private static void debugLogState(String name, long state) { if (log.isDebugEnabled()) { log.debug( "%s[bufferWatermark=%d, parties=%d, isSealed=%s]", name, bufferWatermark(state), parties(state), isSealed(state) ); } } }
private boolean needsToShutdown() { boolean needsToShutdown = Thread.interrupted() || shuttingDown; if (needsToShutdown) { Object lastBatch = concurrentBatch.getAndSet(null); if (lastBatch instanceof Batch) { ((Batch) lastBatch).seal(); } } else { Object batch = concurrentBatch.get(); if (batch instanceof Batch) { ((Batch) batch).sealIfFlushNeeded(); } else { // batch == null means that HttpPostEmitter is terminated. Batch object could also be Integer, if some // thread just failed with a serious error in onSealExclusive(), in this case we don't want to shutdown // the emitter thread. needsToShutdown = batch == null; } } return needsToShutdown; }
batch.awaitEmittingAllowed(); try { final int bufferWatermark = batch.getSealedBufferWatermark(); if (bufferWatermark == 0) { // sealed while empty return;
void sealIfFlushNeeded() { long timeSinceFirstEvent = System.currentTimeMillis() - firstEventTimestamp; if (firstEventTimestamp > 0 && timeSinceFirstEvent > emitter.config.getFlushMillis()) { seal(); } }
Batch batch = eventBatchesPerThread.get(threadIndex).get(indexOfEvent); System.err.println(batch); int bufferWatermark = batch.getSealedBufferWatermark(); ByteBuffer batchBuffer = ByteBuffer.wrap(batch.buffer); batchBuffer.limit(bufferWatermark);
private boolean tryReserveFirstEventSizeAndLock(byte[] event) { return compareAndSetState(0, emitter.batchingStrategy.batchStartLength() + event.length + PARTY); }
long state = getState(); int parties = parties(state); if (parties == 0) { throw new IllegalMonitorStateException(); if (compareAndSetState(state, newState)) { return isEmittingAllowed(newState); long state = getState(); int parties = parties(state); if (parties == 0) { throw new IllegalMonitorStateException(); if (compareAndSetState(state, newState)) { if (!isSealed(state)) { log.debug("Unlocked and sealed batch [%d]", batchNumber); debugLogState("old state", state); debugLogState("new state", newState); emitter.onSealExclusive( this, return isEmittingAllowed(newState); long state = getState(); if (isSealed(state)) { if (compareAndSetState(state, newState)) { log.debug("Sealed batch [%d]", batchNumber);
@Override public String toString() { long state = getState(); return "Batch{" + "batchNumber=" + batchNumber + ", bufferWatermark=" + bufferWatermark(state) + ", parties=" + parties(state) + ", isSealed=" + isSealed(state) + "}"; }
/** * Returns the buffer offset at which the caller has reserved the ability to write `size` bytes exclusively, * or negative number, if the reservation attempt failed. */ private int tryReserveEventSizeAndLock(long state, int size) { Preconditions.checkArgument(size > 0); int bufferWatermark = bufferWatermark(state); while (true) { if (compareAndSetState(state, state + size + PARTY)) { return bufferWatermark; } state = getState(); if (isSealed(state)) { return -1; } bufferWatermark = bufferWatermark(state); int newBufferWatermark = bufferWatermark + size; Preconditions.checkState(newBufferWatermark > 0); if (newBufferWatermark > emitter.maxBufferWatermark) { return -1; } } }
int getSealedBufferWatermark() { long state = getState(); Preconditions.checkState(isSealed(state)); return bufferWatermark(state); }
private static void debugLogState(String name, long state) { if (log.isDebugEnabled()) { log.debug( "%s[bufferWatermark=%d, parties=%d, isSealed=%s]", name, bufferWatermark(state), parties(state), isSealed(state) ); } } }
private boolean needsToShutdown() { boolean needsToShutdown = Thread.interrupted() || shuttingDown; if (needsToShutdown) { Object lastBatch = concurrentBatch.getAndSet(null); if (lastBatch instanceof Batch) { ((Batch) lastBatch).seal(); } } else { Object batch = concurrentBatch.get(); if (batch instanceof Batch) { ((Batch) batch).sealIfFlushNeeded(); } else { // batch == null means that HttpPostEmitter is terminated. Batch object could also be Integer, if some // thread just failed with a serious error in onSealExclusive(), in this case we don't want to shutdown // the emitter thread. needsToShutdown = batch == null; } } return needsToShutdown; }