private boolean isDrained() { long minSubscriberPosition = Long.MAX_VALUE; for (final ReadablePosition subscriberPosition : subscriberPositions) { minSubscriberPosition = Math.min(minSubscriberPosition, subscriberPosition.getVolatile()); } return minSubscriberPosition >= rebuildPosition.get(); }
/** {@inheritDoc} */ public void close() { hwmPosition.close(); rebuildPosition.close(); for (final ReadablePosition position : subscriberPositions) { position.close(); } congestionControl.close(); rawLog.close(); }
/** * Called from the {@link DriverConductor}. * * @param now in nanoseconds * @param statusMessageTimeout for sending of Status Messages. */ void trackRebuild(final long now, final long statusMessageTimeout) { long minSubscriberPosition = Long.MAX_VALUE; long maxSubscriberPosition = Long.MIN_VALUE; for (final ReadablePosition subscriberPosition : subscriberPositions) { final long position = subscriberPosition.getVolatile(); minSubscriberPosition = Math.min(minSubscriberPosition, position); maxSubscriberPosition = Math.max(maxSubscriberPosition, position); } final long rebuildPosition = Math.max(this.rebuildPosition.get(), maxSubscriberPosition); final long hwmPosition = this.hwmPosition.getVolatile(); final long scanOutcome = lossDetector.scan( termBuffers[indexByPosition(rebuildPosition, positionBitsToShift)], rebuildPosition, hwmPosition, now, termLengthMask, positionBitsToShift, initialTermId); final int rebuildTermOffset = (int) rebuildPosition & termLengthMask; final long newRebuildPosition = (rebuildPosition - rebuildTermOffset) + rebuildOffset(scanOutcome); this.rebuildPosition.proposeMaxOrdered(newRebuildPosition); final long ccOutcome = congestionControl.onTrackRebuild( now, minSubscriberPosition, nextSmPosition, hwmPosition, rebuildPosition, newRebuildPosition, lossFound(scanOutcome)); final int window = CongestionControlUtil.receiverWindowLength(ccOutcome); final long threshold = CongestionControlUtil.positionThreshold(window); if (CongestionControlUtil.shouldForceStatusMessage(ccOutcome) || (now > (lastStatusMessageTimestamp + statusMessageTimeout)) || (minSubscriberPosition > (nextSmPosition + threshold))) { scheduleStatusMessage(now, minSubscriberPosition, window); cleanBufferTo(minSubscriberPosition - (termLengthMask + 1)); } }
@Before public void setUp() { when(publicationLimit.getVolatile()).thenReturn(2L * SEND_BUFFER_CAPACITY); when(logBuffers.termBuffers()).thenReturn(termBuffers); when(logBuffers.termLength()).thenReturn(TERM_MIN_LENGTH); when(logBuffers.metaDataBuffer()).thenReturn(logMetaDataBuffer); when(conductor.mainLock()).thenReturn(conductorLock); initialTermId(logMetaDataBuffer, TERM_ID_1); timeOfLastStatusMessage(logMetaDataBuffer, 0); for (int i = 0; i < PARTITION_COUNT; i++) { termBuffers[i] = new UnsafeBuffer(allocateDirect(TERM_MIN_LENGTH)); } publication = new Publication( conductor, CHANNEL, STREAM_ID_1, SESSION_ID_1, publicationLimit, logBuffers, CORRELATION_ID); publication.incRef(); initialiseTailWithTermId(logMetaDataBuffer, PARTITION_INDEX, TERM_ID_1); }
/** * Remove a {@link ReadablePosition} for a subscriber that has been removed so it is not tracked * for flow control. * * @param subscriberPosition for the subscriber that has been removed. */ void removeSubscriber(final ReadablePosition subscriberPosition) { subscriberPositions = ArrayUtil.remove(subscriberPositions, subscriberPosition); subscriberPosition.close(); }
@Test public void shouldReportThatPublicationHasNotBeenConnectedYet() { when(publicationLimit.getVolatile()).thenReturn(0L); when(conductor.isPublicationConnected(anyLong())).thenReturn(false); assertFalse(publication.isConnected()); }