@Test
  public void shouldReceiveFirstMessageFromBuffer() {
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long tail = recordLengthAligned;
    final long latestRecord = tail - recordLengthAligned;
    final int recordOffset = (int) latestRecord;

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET)).thenReturn(tail);
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);
    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext());
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertTrue(broadcastReceiver.validate());

    final InOrder inOrder = inOrder(buffer);
    inOrder.verify(buffer).getLongVolatile(TAIL_COUNTER_INDEX);
    inOrder.verify(buffer).getLongVolatile(TAIL_INTENT_COUNTER_OFFSET);
  }
  @Before
  public void setUp() {
    when(termBuffer.capacity()).thenReturn(TERM_BUFFER_LENGTH);
    when(metaDataBuffer.capacity()).thenReturn(META_DATA_BUFFER_LENGTH);

    termAppender = new TermAppender(termBuffer, metaDataBuffer, DEFAULT_HEADER, MAX_FRAME_LENGTH);
  }
  @Test
  public void shouldDealWithRecordBecomingInvalidDueToOverwrite() {
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long tail = recordLengthAligned;
    final long latestRecord = tail - recordLengthAligned;
    final int recordOffset = (int) latestRecord;

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET))
        .thenReturn(tail)
        .thenReturn(tail + (CAPACITY - (recordLengthAligned)));
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);

    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext());
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertFalse(
        broadcastReceiver.validate()); // Need to receiveNext() to catch up with transmission again.

    final InOrder inOrder = inOrder(buffer);
    inOrder.verify(buffer).getLongVolatile(TAIL_COUNTER_INDEX);
  }
Exemple #4
0
  public int appendUnfragmentedMessage(
      final long defaultVersionFlagsType,
      final long defaultSessionId,
      final DirectBuffer srcBuffer,
      final int srcOffset,
      final int length) {
    final int frameLength = length + HEADER_LENGTH;
    final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
    final int termOffset = metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedLength);
    final UnsafeBuffer termBuffer = this.termBuffer;
    final int capacity = termBuffer.capacity();

    int resultingOffset = termOffset + alignedLength;
    if (resultingOffset > (capacity - HEADER_LENGTH)) {
      resultingOffset =
          handleEndOfLogCondition(
              termBuffer, termOffset, defaultVersionFlagsType, defaultSessionId, capacity);
    } else {
      applyDefaultHeader(
          termBuffer, termOffset, frameLength, defaultVersionFlagsType, defaultSessionId);
      termBuffer.putBytes(termOffset + HEADER_LENGTH, srcBuffer, srcOffset, length);
      frameLengthOrdered(termBuffer, termOffset, frameLength);
    }

    return resultingOffset;
  }
Exemple #5
0
  private void applyDefaultHeader(
      final UnsafeBuffer buffer,
      final int termOffset,
      final int frameLength,
      final long defaultVersionFlagsType,
      final long defaultSessionId) {
    long lengthVersionFlagsType;
    long termOffsetAndSessionId;

    if (ByteOrder.nativeOrder() == LITTLE_ENDIAN) {
      lengthVersionFlagsType = defaultVersionFlagsType | ((-frameLength) & 0xFFFF_FFFFL);
      termOffsetAndSessionId = defaultSessionId | termOffset;
    } else {
      lengthVersionFlagsType =
          (((reverseBytes(-frameLength)) & 0xFFFF_FFFFL) << 32) | defaultVersionFlagsType;
      termOffsetAndSessionId =
          (((reverseBytes(termOffset)) & 0xFFFF_FFFFL) << 32) | defaultSessionId;
    }

    buffer.putLongOrdered(termOffset + FRAME_LENGTH_FIELD_OFFSET, lengthVersionFlagsType);
    UnsafeAccess.UNSAFE.storeFence();

    buffer.putLong(termOffset + TERM_OFFSET_FIELD_OFFSET, termOffsetAndSessionId);

    // read the stream(int) and term(int), this is the mutable part of the default header
    final long streamAndTermIds = defaultHeader.getLong(STREAM_ID_FIELD_OFFSET);
    buffer.putLong(termOffset + STREAM_ID_FIELD_OFFSET, streamAndTermIds);
  }
  @Test
  public void shouldLateJoinTransmission() {
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long tail = (CAPACITY * 3L) + HEADER_LENGTH + recordLengthAligned;
    final long latestRecord = tail - recordLengthAligned;
    final int recordOffset = (int) latestRecord & (CAPACITY - 1);

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET)).thenReturn(tail);
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);
    when(buffer.getLong(LATEST_COUNTER_INDEX)).thenReturn(latestRecord);

    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext());
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertTrue(broadcastReceiver.validate());
    assertThat(broadcastReceiver.lappedCount(), is(greaterThan(0L)));
  }
  @Test
  public void shouldReportCurrentTailAtCapacity() {
    final int tailValue = TERM_BUFFER_LENGTH + 64;

    when(metaDataBuffer.getIntVolatile(TERM_TAIL_COUNTER_OFFSET)).thenReturn(tailValue);
    when(metaDataBuffer.getInt(TERM_TAIL_COUNTER_OFFSET)).thenReturn(tailValue);

    assertThat(termAppender.tailVolatile(), is(TERM_BUFFER_LENGTH));
    assertThat(termAppender.tail(), is(TERM_BUFFER_LENGTH));
  }
Exemple #8
0
  public int appendFragmentedMessage(
      final long defaultVersionFlagsType,
      final long defaultSessionId,
      final DirectBuffer srcBuffer,
      final int srcOffset,
      final int length,
      final int maxPayloadLength) {
    final int numMaxPayloads = length / maxPayloadLength;
    final int remainingPayload = length % maxPayloadLength;
    final int lastFrameLength =
        (remainingPayload > 0) ? align(remainingPayload + HEADER_LENGTH, FRAME_ALIGNMENT) : 0;
    final int requiredLength =
        (numMaxPayloads * (maxPayloadLength + HEADER_LENGTH)) + lastFrameLength;
    int termOffset = metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, requiredLength);
    final UnsafeBuffer termBuffer = this.termBuffer;
    final int capacity = termBuffer.capacity();

    int resultingOffset = termOffset + requiredLength;
    if (resultingOffset > (capacity - HEADER_LENGTH)) {
      resultingOffset =
          handleEndOfLogCondition(
              termBuffer, termOffset, defaultVersionFlagsType, defaultSessionId, capacity);
    } else {
      byte flags = BEGIN_FRAG_FLAG;
      int remaining = length;
      do {
        final int bytesToWrite = Math.min(remaining, maxPayloadLength);
        final int frameLength = bytesToWrite + HEADER_LENGTH;
        final int alignedLength = align(frameLength, FRAME_ALIGNMENT);

        applyDefaultHeader(
            termBuffer, termOffset, frameLength, defaultVersionFlagsType, defaultSessionId);
        termBuffer.putBytes(
            termOffset + HEADER_LENGTH, srcBuffer, srcOffset + (length - remaining), bytesToWrite);

        if (remaining <= maxPayloadLength) {
          flags |= END_FRAG_FLAG;
        }

        frameFlags(termBuffer, termOffset, flags);
        frameLengthOrdered(termBuffer, termOffset, frameLength);

        flags = 0;
        termOffset += alignedLength;
        remaining -= bytesToWrite;
      } while (remaining > 0);
    }

    return resultingOffset;
  }
  @Test
  public void shouldPadLogAndTripWhenAppendingWithInsufficientRemainingCapacityIncludingHeader() {
    final int headerLength = DEFAULT_HEADER.capacity();
    final int msgLength = 120;
    final int requiredFrameSize = align(headerLength + msgLength, FRAME_ALIGNMENT);
    final int tailValue =
        termAppender.termBuffer().capacity()
            - (requiredFrameSize + (headerLength - FRAME_ALIGNMENT));
    final UnsafeBuffer buffer = new UnsafeBuffer(new byte[128]);
    final int frameLength = TERM_BUFFER_LENGTH - tailValue;

    when(metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, requiredFrameSize))
        .thenReturn(tailValue);

    assertThat(termAppender.append(buffer, 0, msgLength), is(TermAppender.TRIPPED));

    final InOrder inOrder = inOrder(termBuffer, metaDataBuffer);
    inOrder
        .verify(metaDataBuffer, times(1))
        .getAndAddInt(TERM_TAIL_COUNTER_OFFSET, requiredFrameSize);
    verifyDefaultHeader(inOrder, termBuffer, tailValue, frameLength);
    inOrder
        .verify(termBuffer, times(1))
        .putShort(typeOffset(tailValue), (short) PADDING_FRAME_TYPE, LITTLE_ENDIAN);
    inOrder
        .verify(termBuffer, times(1))
        .putInt(termOffsetOffset(tailValue), tailValue, LITTLE_ENDIAN);
    inOrder.verify(termBuffer, times(1)).putIntOrdered(tailValue, frameLength);
  }
  @Test
  public void shouldClaimRegionForZeroCopyEncoding() {
    final int headerLength = DEFAULT_HEADER.capacity();
    final int msgLength = 20;
    final int frameLength = msgLength + headerLength;
    final int alignedFrameLength = align(frameLength, FRAME_ALIGNMENT);
    final int tail = 0;
    final BufferClaim bufferClaim = new BufferClaim();

    when(metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedFrameLength)).thenReturn(0);

    assertThat(termAppender.claim(msgLength, bufferClaim), is(alignedFrameLength));

    assertThat(bufferClaim.offset(), is(tail + headerLength));
    assertThat(bufferClaim.length(), is(msgLength));

    // Map flyweight or encode to buffer directly then call commit() when done
    bufferClaim.commit();

    final InOrder inOrder = inOrder(termBuffer, metaDataBuffer);
    inOrder
        .verify(metaDataBuffer, times(1))
        .getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedFrameLength);
    verifyDefaultHeader(inOrder, termBuffer, tail, frameLength);
    inOrder.verify(termBuffer, times(1)).putInt(termOffsetOffset(tail), tail, LITTLE_ENDIAN);
  }
  @Test
  public void shouldTransmitIntoUsedBuffer() {
    final long tail = RECORD_ALIGNMENT * 3;
    final int recordOffset = (int) tail;
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);

    when(buffer.getLong(TAIL_COUNTER_INDEX)).thenReturn(tail);

    final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[1024]);
    final int srcIndex = 0;

    broadcastTransmitter.transmit(MSG_TYPE_ID, srcBuffer, srcIndex, length);

    final InOrder inOrder = inOrder(buffer);
    inOrder.verify(buffer).getLong(TAIL_COUNTER_INDEX);

    inOrder.verify(buffer).putLong(TAIL_INTENT_COUNTER_OFFSET, tail + recordLengthAligned);
    inOrder.verify(buffer).putInt(lengthOffset(recordOffset), recordLength);
    inOrder.verify(buffer).putInt(typeOffset(recordOffset), MSG_TYPE_ID);
    inOrder.verify(buffer).putBytes(msgOffset(recordOffset), srcBuffer, srcIndex, length);

    inOrder.verify(buffer).putLong(LATEST_COUNTER_INDEX, tail);
    inOrder.verify(buffer).putLongOrdered(TAIL_COUNTER_INDEX, tail + recordLengthAligned);
  }
  @Test
  public void shouldAppendFrameTwiceToLog() {
    final int headerLength = DEFAULT_HEADER.capacity();
    final UnsafeBuffer buffer = new UnsafeBuffer(new byte[128]);
    final int msgLength = 20;
    final int frameLength = msgLength + headerLength;
    final int alignedFrameLength = align(frameLength, FRAME_ALIGNMENT);
    int tail = 0;

    when(metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedFrameLength))
        .thenReturn(0)
        .thenReturn(alignedFrameLength);

    assertThat(termAppender.append(buffer, 0, msgLength), is(alignedFrameLength));
    assertThat(termAppender.append(buffer, 0, msgLength), is(alignedFrameLength * 2));

    final InOrder inOrder = inOrder(termBuffer, metaDataBuffer);
    inOrder
        .verify(metaDataBuffer, times(1))
        .getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedFrameLength);
    verifyDefaultHeader(inOrder, termBuffer, tail, frameLength);
    inOrder.verify(termBuffer, times(1)).putBytes(headerLength, buffer, 0, msgLength);
    inOrder.verify(termBuffer, times(1)).putInt(termOffsetOffset(tail), tail, LITTLE_ENDIAN);
    inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, frameLength);

    tail = alignedFrameLength;
    inOrder
        .verify(metaDataBuffer, times(1))
        .getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedFrameLength);
    verifyDefaultHeader(inOrder, termBuffer, tail, frameLength);
    inOrder.verify(termBuffer, times(1)).putBytes(tail + headerLength, buffer, 0, msgLength);
    inOrder.verify(termBuffer, times(1)).putInt(termOffsetOffset(tail), tail, LITTLE_ENDIAN);
    inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, frameLength);
  }
  @Test(expected = IllegalStateException.class)
  public void shouldThrowExceptionWhenCapacityNotMultipleOfAlignment() {
    final int logBufferCapacity = LogBufferDescriptor.TERM_MIN_LENGTH + FRAME_ALIGNMENT + 1;
    when(termBuffer.capacity()).thenReturn(logBufferCapacity);

    termAppender = new TermAppender(termBuffer, metaDataBuffer, DEFAULT_HEADER, MAX_FRAME_LENGTH);
  }
  @Test
  public void shouldApplyPaddingWhenInsufficientSpaceAtEndOfBuffer() {
    long tail = CAPACITY - RECORD_ALIGNMENT;
    int recordOffset = (int) tail;
    final int length = RECORD_ALIGNMENT + 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final int toEndOfBuffer = CAPACITY - recordOffset;

    when(buffer.getLong(TAIL_COUNTER_INDEX)).thenReturn(tail);

    final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[1024]);
    final int srcIndex = 0;

    broadcastTransmitter.transmit(MSG_TYPE_ID, srcBuffer, srcIndex, length);

    final InOrder inOrder = inOrder(buffer);
    inOrder.verify(buffer).getLong(TAIL_COUNTER_INDEX);

    inOrder
        .verify(buffer)
        .putLong(TAIL_INTENT_COUNTER_OFFSET, tail + recordLengthAligned + toEndOfBuffer);

    inOrder.verify(buffer).putInt(lengthOffset(recordOffset), toEndOfBuffer);
    inOrder.verify(buffer).putInt(typeOffset(recordOffset), PADDING_MSG_TYPE_ID);

    tail += toEndOfBuffer;
    recordOffset = 0;
    inOrder.verify(buffer).putInt(lengthOffset(recordOffset), recordLength);
    inOrder.verify(buffer).putInt(typeOffset(recordOffset), MSG_TYPE_ID);
    inOrder.verify(buffer).putBytes(msgOffset(recordOffset), srcBuffer, srcIndex, length);

    inOrder.verify(buffer).putLong(LATEST_COUNTER_INDEX, tail);
    inOrder.verify(buffer).putLongOrdered(TAIL_COUNTER_INDEX, tail + recordLengthAligned);
  }
  @Test(expected = IllegalStateException.class)
  public void shouldThrowExceptionForCapacityThatIsNotPowerOfTwo() {
    final int capacity = 777;
    final int totalBufferLength = capacity + BroadcastBufferDescriptor.TRAILER_LENGTH;

    when(buffer.capacity()).thenReturn(totalBufferLength);

    new BroadcastReceiver(buffer);
  }
  public int onNext() {
    while (pub.tryClaim(buffer.capacity(), bufferClaim) < 0L) {}

    final MutableDirectBuffer buffer = bufferClaim.buffer();
    final int offset = bufferClaim.offset();
    buffer.putByte(offset, (byte) 'p');
    buffer.putInt(offset + 1, msgCount++);
    buffer.putLong(offset + 5, System.nanoTime());
    bufferClaim.commit();
    return msgLen;
  }
Exemple #17
0
  public int claim(
      final long defaultVersionFlagsType,
      final long defaultSessionId,
      final int length,
      final BufferClaim bufferClaim) {
    final int frameLength = length + HEADER_LENGTH;
    final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
    final int termOffset = metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, alignedLength);
    final UnsafeBuffer termBuffer = this.termBuffer;
    final int capacity = termBuffer.capacity();

    int resultingOffset = termOffset + alignedLength;
    if (resultingOffset > (capacity - HEADER_LENGTH)) {
      resultingOffset =
          handleEndOfLogCondition(
              termBuffer, termOffset, defaultVersionFlagsType, defaultSessionId, capacity);
    } else {
      applyDefaultHeader(
          termBuffer, termOffset, frameLength, defaultVersionFlagsType, defaultSessionId);
      bufferClaim.wrap(termBuffer, termOffset, frameLength);
    }

    return resultingOffset;
  }
Exemple #18
0
  /**
   * Attempt to unblock the current term at the current offset.
   *
   * <ol>
   *   <li>Current position length is &gt; 0, then return
   *   <li>Current position length is 0, scan forward by frame alignment until, one of the
   *       following:
   *       <ol>
   *         <li>reach a non-0 length, unblock up to indicated position (check original frame length
   *             for non-0)
   *         <li>reach end of term and tail position &gt;= end of term, unblock up to end of term
   *             (check original frame length for non-0)
   *         <li>reach tail position &lt; end of term, do NOT unblock
   *       </ol>
   * </ol>
   *
   * @param logMetaDataBuffer containing the default headers
   * @param activeIndex for the default header
   * @param termBuffer to unblock
   * @param termOffset to unblock at
   * @param tailOffset to unblock up to
   * @return whether unblocking was done, not done, or applied to end of term
   */
  public static Status unblock(
      final UnsafeBuffer logMetaDataBuffer,
      final int activeIndex,
      final UnsafeBuffer termBuffer,
      final int termOffset,
      final int tailOffset) {
    Status status = NO_ACTION;
    int frameLength = frameLengthVolatile(termBuffer, termOffset);

    if (frameLength < 0) {
      resetHeader(logMetaDataBuffer, activeIndex, termBuffer, termOffset, -frameLength);
      status = UNBLOCKED;
    } else if (0 == frameLength) {
      int currentOffset = termOffset + FRAME_ALIGNMENT;

      while (currentOffset < tailOffset) {
        frameLength = frameLengthVolatile(termBuffer, currentOffset);

        if (frameLength != 0) {
          if (scanBackToConfirmZeroed(termBuffer, currentOffset, termOffset)) {
            resetHeader(
                logMetaDataBuffer, activeIndex, termBuffer, termOffset, currentOffset - termOffset);
            status = UNBLOCKED;
          }

          break;
        }

        currentOffset += FRAME_ALIGNMENT;
      }

      if (currentOffset == termBuffer.capacity()) {
        if (0 == frameLengthVolatile(termBuffer, termOffset)) {
          resetHeader(
              logMetaDataBuffer, activeIndex, termBuffer, termOffset, currentOffset - termOffset);
          status = UNBLOCKED_TO_END;
        }
      }
    }

    return status;
  }
  @Test
  public void shouldCopeWithPaddingRecordAndWrapOfBufferForNextRecord() {
    final int length = 120;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long catchupTail = (CAPACITY * 2L) - HEADER_LENGTH;
    final long postPaddingTail = catchupTail + HEADER_LENGTH + recordLengthAligned;
    final long latestRecord = catchupTail - recordLengthAligned;
    final int catchupOffset = (int) latestRecord & (CAPACITY - 1);

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET))
        .thenReturn(catchupTail)
        .thenReturn(postPaddingTail);
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX))
        .thenReturn(catchupTail)
        .thenReturn(postPaddingTail);
    when(buffer.getLong(LATEST_COUNTER_INDEX)).thenReturn(latestRecord);
    when(buffer.getInt(lengthOffset(catchupOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(catchupOffset))).thenReturn(MSG_TYPE_ID);

    final int paddingOffset = (int) catchupTail & (CAPACITY - 1);
    final int recordOffset = (int) (postPaddingTail - recordLengthAligned) & (CAPACITY - 1);
    when(buffer.getInt(typeOffset(paddingOffset))).thenReturn(PADDING_MSG_TYPE_ID);

    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext()); // To catch up to record before padding.

    assertTrue(broadcastReceiver.receiveNext()); // no skip over the padding and read next record.
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertTrue(broadcastReceiver.validate());
  }
  @Test
  public void shouldFragmentMessageOverTwoFrames() {
    final int msgLength = termAppender.maxPayloadLength() + 1;
    final int headerLength = DEFAULT_HEADER.capacity();
    final int frameLength = headerLength + 1;
    final int requiredCapacity =
        align(headerLength + 1, FRAME_ALIGNMENT) + termAppender.maxFrameLength();
    final UnsafeBuffer buffer = new UnsafeBuffer(new byte[msgLength]);

    when(metaDataBuffer.getAndAddInt(TERM_TAIL_COUNTER_OFFSET, requiredCapacity)).thenReturn(0);

    assertThat(termAppender.append(buffer, 0, msgLength), is(requiredCapacity));

    int tail = 0;
    final InOrder inOrder = inOrder(termBuffer, metaDataBuffer);
    inOrder
        .verify(metaDataBuffer, times(1))
        .getAndAddInt(TERM_TAIL_COUNTER_OFFSET, requiredCapacity);

    verifyDefaultHeader(inOrder, termBuffer, tail, termAppender.maxFrameLength());
    inOrder
        .verify(termBuffer, times(1))
        .putBytes(tail + headerLength, buffer, 0, termAppender.maxPayloadLength());
    inOrder.verify(termBuffer, times(1)).putByte(flagsOffset(tail), BEGIN_FRAG);
    inOrder.verify(termBuffer, times(1)).putInt(termOffsetOffset(tail), tail, LITTLE_ENDIAN);
    inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, termAppender.maxFrameLength());

    tail = termAppender.maxFrameLength();
    verifyDefaultHeader(inOrder, termBuffer, tail, frameLength);
    inOrder
        .verify(termBuffer, times(1))
        .putBytes(tail + headerLength, buffer, termAppender.maxPayloadLength(), 1);
    inOrder.verify(termBuffer, times(1)).putByte(flagsOffset(tail), END_FRAG);
    inOrder.verify(termBuffer, times(1)).putInt(termOffsetOffset(tail), tail, LITTLE_ENDIAN);
    inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, frameLength);
  }
Exemple #21
0
 /**
  * Get the current tail value in a volatile memory ordering fashion. If raw tail is greater than
  * term capacity then capacity will be returned.
  *
  * @return the current tail value.
  */
 public int tailVolatile() {
   return Math.min(metaDataBuffer.getIntVolatile(TERM_TAIL_COUNTER_OFFSET), termBuffer.capacity());
 }
Exemple #22
0
 /**
  * Get the raw value current tail value in a volatile memory ordering fashion.
  *
  * @return the current tail value.
  */
 public int rawTailVolatile() {
   return metaDataBuffer.getIntVolatile(TERM_TAIL_COUNTER_OFFSET);
 }
  @Before
  public void setUp() {
    when(buffer.capacity()).thenReturn(TOTAL_BUFFER_LENGTH);

    broadcastReceiver = new BroadcastReceiver(buffer);
  }
  public AeronLatencyUnderLoadPublisher(final String[] args) {
    try {
      parseArgs(args);
    } catch (final ParseException e) {
      throw new RuntimeException(e);
    }
    final Aeron.Context ctx = new Aeron.Context().newImageHandler(this::imageHandler);
    fragmentHandler = new FragmentAssembler(this::msgHandler);
    final Aeron aeron = Aeron.connect(ctx);
    System.out.println("Reflect: " + reflectChannel + " Pub: " + pubChannel);
    pub = aeron.addPublication(pubChannel, pubStreamId);
    sub = aeron.addSubscription(reflectChannel, subStreamId);
    imageLatch = new CountDownLatch(1);
    final IdleStrategy idle = new BusySpinIdleStrategy();
    bufferClaim = new BufferClaim();

    final List<RateControllerInterval> intervals = new ArrayList<>();
    intervals.add(new MessagesAtMessagesPerSecondInterval(100, 10));
    intervals.add(new MessagesAtMessagesPerSecondInterval(1000, 100));
    intervals.add(new MessagesAtMessagesPerSecondInterval(10000, 1000));
    intervals.add(new MessagesAtMessagesPerSecondInterval(100000, 10000));
    intervals.add(new MessagesAtMessagesPerSecondInterval(1000000, 100000));
    intervals.add(new MessagesAtMessagesPerSecondInterval(10000000, 1000000));
    intervals.add(new MessagesAtMessagesPerSecondInterval(30000000, 3000000));
    buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(msgLen));
    msgCount = 0;

    RateController rateController = null;
    try {
      rateController = new RateController(this, intervals);
    } catch (final Exception ex) {
      throw new RuntimeException(ex);
    }

    final Runnable task =
        () -> {
          while (running) {
            while (sub.poll(fragmentHandler, 1) <= 0 && running) {}
          }
          System.out.println("Done");
        };
    final Thread subThread = new Thread(task);
    subThread.start();

    try {
      imageLatch.await();
    } catch (final InterruptedException e) {
      e.printStackTrace();
    }

    final int warmUpMsgs = 100000;
    for (int i = 0; i < warmUpMsgs; i++) {
      while (pub.tryClaim(buffer.capacity(), bufferClaim) < 0L) {
        idle.idle(1);
      }
      final MutableDirectBuffer buffer = bufferClaim.buffer();
      final int offset = bufferClaim.offset();
      buffer.putByte(offset, (byte) 'w');
      bufferClaim.commit();
    }
    try {
      Thread.sleep(1000);
    } catch (final InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("warmup msgs received: " + warmups);
    final int start = (int) System.currentTimeMillis();
    while (rateController.next()) {}

    final int total = (int) (System.currentTimeMillis() - start) / 1000;
    buffer.putByte(0, (byte) 'q');

    while (pub.offer(buffer, 0, buffer.capacity()) < 0L) {
      idle.idle(0);
    }

    System.out.println("Duration: " + total + " seconds");
    try {
      Thread.sleep(1000);
    } catch (final InterruptedException e) {
      e.printStackTrace();
    }

    running = false;

    try {
      subThread.join();
    } catch (final InterruptedException e) {
      e.printStackTrace();
    }

    aeron.close();

    try {
      computeStats();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Exemple #25
0
 /**
  * Set the status of the log buffer with StoreStore memory ordering semantics.
  *
  * @param status to be set for the log buffer.
  */
 public void statusOrdered(final int status) {
   metaDataBuffer.putIntOrdered(TERM_STATUS_OFFSET, status);
 }
 private void addSentDataFrame() {
   rcvBuffer.putBytes(0, DATA);
   termAppender.append(rcvBuffer, 0, DATA.length);
 }
  @Test(expected = IllegalStateException.class)
  public void shouldThrowExceptionOnInsufficientMetaDataBufferCapacity() {
    when(metaDataBuffer.capacity()).thenReturn(LogBufferDescriptor.TERM_META_DATA_LENGTH - 1);

    termAppender = new TermAppender(termBuffer, metaDataBuffer, DEFAULT_HEADER, MAX_FRAME_LENGTH);
  }