/** * Called from the {@link Receiver} thread to processing any pending loss of packets. * * @return number of work items processed. */ int processPendingLoss() { int workCount = 0; final long changeNumber = endLossChange; if (changeNumber != lastLossChangeNumber) { final int termId = lossTermId; final int termOffset = lossTermOffset; final int length = lossLength; UNSAFE .loadFence(); // LoadLoad required so previous loads don't move past version check below. if (changeNumber == beginLossChange) { if (isReliable) { channelEndpoint.sendNakMessage( controlAddress, sessionId, streamId, termId, termOffset, length); nakMessagesSent.orderedIncrement(); } else { final UnsafeBuffer termBuffer = termBuffers[indexByTerm(initialTermId, termId)]; if (tryFillGap(rawLog.logMetaData(), termBuffer, termId, termOffset, length)) { lossGapFills.orderedIncrement(); } } lastLossChangeNumber = changeNumber; workCount = 1; } } return workCount; }
private boolean isFlowControlUnderRun(final long windowPosition, final long packetPosition) { final boolean isFlowControlUnderRun = packetPosition < windowPosition; if (isFlowControlUnderRun) { flowControlUnderRuns.orderedIncrement(); } return isFlowControlUnderRun; }
private boolean isFlowControlOverRun(final long windowPosition, final long proposedPosition) { final boolean isFlowControlOverRun = proposedPosition > (windowPosition + nextSmReceiverWindowLength); if (isFlowControlOverRun) { flowControlOverRuns.orderedIncrement(); } return isFlowControlOverRun; }
private int doSend(final long now) { int bytesSent = 0; final NetworkPublication[] publications = this.networkPublications; final int length = publications.length; int startingIndex = roundRobinIndex++; if (startingIndex >= length) { roundRobinIndex = startingIndex = 0; } for (int i = startingIndex; i < length; i++) { bytesSent += publications[i].send(now); } for (int i = 0; i < startingIndex; i++) { bytesSent += publications[i].send(now); } totalBytesSent.addOrdered(bytesSent); return bytesSent; }
/** * Insert frame into term buffer. * * @param termId for the data packet to insert into the appropriate term. * @param termOffset for the start of the packet in the term. * @param buffer for the data packet to insert into the appropriate term. * @param length of the data packet * @return number of bytes applied as a result of this insertion. */ int insertPacket( final int termId, final int termOffset, final UnsafeBuffer buffer, final int length) { final boolean isHeartbeat = isHeartbeat(buffer, length); final long packetPosition = computePosition(termId, termOffset, positionBitsToShift, initialTermId); final long proposedPosition = isHeartbeat ? packetPosition : packetPosition + length; final long windowPosition = nextSmPosition; if (!isFlowControlUnderRun(windowPosition, packetPosition) && !isFlowControlOverRun(windowPosition, proposedPosition)) { if (isHeartbeat) { heartbeatsReceived.orderedIncrement(); } else { final UnsafeBuffer termBuffer = termBuffers[indexByPosition(packetPosition, positionBitsToShift)]; TermRebuilder.insert(termBuffer, termOffset, buffer, length); } hwmCandidate(proposedPosition); } return length; }
/** * Called from the {@link Receiver} to send any pending Status Messages. * * @return number of work items processed. */ int sendPendingStatusMessage() { int workCount = 0; if (ACTIVE == status) { final long changeNumber = endSmChange; if (changeNumber != lastSmChangeNumber) { final long smPosition = nextSmPosition; final int receiverWindowLength = nextSmReceiverWindowLength; UNSAFE.loadFence(); // LoadLoad required so previous loads don't move past version check // below. if (changeNumber == beginSmChange) { final int termId = computeTermIdFromPosition(smPosition, positionBitsToShift, initialTermId); final int termOffset = (int) smPosition & termLengthMask; channelEndpoint.sendStatusMessage( controlAddress, sessionId, streamId, termId, termOffset, receiverWindowLength, (byte) 0); statusMessagesSent.orderedIncrement(); lastSmChangeNumber = changeNumber; workCount = 1; } } } return workCount; }