/**
   * 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;
  }
Exemple #4
0
  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;
  }