public String toString() { final StringBuilder sb = new StringBuilder(); final String formattedFlags = String.format("%1$8s", Integer.toBinaryString(flags())).replace(' ', '0'); sb.append("STATUS Message{") .append("frame_length=").append(frameLength()) .append(" version=").append(version()) .append(" flags=").append(formattedFlags) .append(" type=").append(headerType()) .append(" session_id=").append(sessionId()) .append(" stream_id=").append(streamId()) .append(" consumption_term_id=").append(consumptionTermId()) .append(" consumption_term_offset=").append(consumptionTermOffset()) .append(" receiver_window_length=").append(receiverWindowLength()) .append("}"); return sb.toString(); } }
private static void dissect(final StatusMessageFlyweight msg, final StringBuilder builder) { builder .append("SM ") .append(msg.flags()) .append(" len ") .append(msg.frameLength()) .append(' ') .append(msg.sessionId()) .append(':') .append(msg.streamId()) .append(':') .append(msg.consumptionTermId()) .append(" @") .append(msg.consumptionTermOffset()) .append(' ') .append(msg.receiverWindowLength()) .append(' ') .append(msg.receiverId()); }
/** * {@inheritDoc} */ public long onStatusMessage( final StatusMessageFlyweight flyweight, final InetSocketAddress receiverAddress, final long senderLimit, final int initialTermId, final int positionBitsToShift, final long timeNs) { final long position = computePosition( flyweight.consumptionTermId(), flyweight.consumptionTermOffset(), positionBitsToShift, initialTermId); lastPosition = Math.max(lastPosition, position); timeOfLastStatusMessage = timeNs; return Math.max(senderLimit, position + flyweight.receiverWindowLength()); }
/** * {@inheritDoc} */ public long onStatusMessage( final StatusMessageFlyweight flyweight, final InetSocketAddress receiverAddress, final long senderLimit, final int initialTermId, final int positionBitsToShift, final long timeNs) { final long position = computePosition( flyweight.consumptionTermId(), flyweight.consumptionTermOffset(), positionBitsToShift, initialTermId); lastPosition = Math.max(lastPosition, position); timeOfLastStatusMessage = timeNs; return Math.max(senderLimit, position + flyweight.receiverWindowLength()); }
flyweight.consumptionTermId(), flyweight.consumptionTermOffset(), positionBitsToShift,
flyweight.consumptionTermId(), flyweight.consumptionTermOffset(), positionBitsToShift,
public void sendSetupElicitingStatusMessage( final int transportIndex, final InetSocketAddress controlAddress, final int sessionId, final int streamId) { if (!isClosed) { smBuffer.clear(); statusMessageFlyweight .sessionId(sessionId) .streamId(streamId) .consumptionTermId(0) .consumptionTermOffset(0) .receiverWindowLength(0) .flags(SEND_SETUP_FLAG); send(smBuffer, StatusMessageFlyweight.HEADER_LENGTH, transportIndex, controlAddress); } }
public void sendStatusMessage( final ImageConnection[] controlAddresses, final int sessionId, final int streamId, final int termId, final int termOffset, final int window, final short flags) { if (!isClosed) { smBuffer.clear(); statusMessageFlyweight .sessionId(sessionId) .streamId(streamId) .consumptionTermId(termId) .consumptionTermOffset(termOffset) .receiverWindowLength(window) .flags(flags); send(smBuffer, StatusMessageFlyweight.HEADER_LENGTH, controlAddresses); } }
@Test public void shouldNotSendSetupFrameAfterReceivingStatusMessage() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(0); publication.onStatusMessage(msg, rcvAddress); // publication.senderPositionLimit(flowControl.onStatusMessage(msg, rcvAddress, )); sender.doWork(); assertThat(receivedFrames.size(), is(1)); receivedFrames.remove(); currentTimestamp += Configuration.PUBLICATION_SETUP_TIMEOUT_NS + 10; sender.doWork(); assertThat(receivedFrames.size(), is(1)); dataHeader.wrap(receivedFrames.remove()); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); // heartbeat assertThat(dataHeader.frameLength(), is(0)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); }
@Test public void shouldSendSetupFrameAfterReceivingStatusMessageWithSetupBit() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(2)); // setup then data receivedFrames.remove(); receivedFrames.remove(); publication.triggerSendSetupFrame(); sender.doWork(); assertThat(receivedFrames.size(), is(0)); // setup has been sent already, have to wait currentTimestamp += Configuration.PUBLICATION_SETUP_TIMEOUT_NS + 10; sender.doWork(); assertThat(receivedFrames.size(), is(1)); setupHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP)); }
@Test public void shouldSendLastDataFrameAsHeartbeatWhenIdle() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(2)); // should send ticks receivedFrames.remove(); // skip setup & data frame receivedFrames.remove(); currentTimestamp += Configuration.PUBLICATION_HEARTBEAT_TIMEOUT_NS - 1; sender.doWork(); assertThat(receivedFrames.size(), is(0)); // should not send yet currentTimestamp += 10; sender.doWork(); assertThat(receivedFrames.size(), greaterThanOrEqualTo(1)); // should send ticks dataHeader.wrap(receivedFrames.remove()); assertThat(dataHeader.frameLength(), is(0)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(2))); }
@Test public void shouldNotSendUntilStatusMessageReceived() { final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(1)); setupHeader.wrap(receivedFrames.remove()); assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP)); final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); sender.doWork(); assertThat(receivedFrames.size(), is(1)); dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.streamId(), is(STREAM_ID)); assertThat(dataHeader.sessionId(), is(SESSION_ID)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(dataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); }
@Test public void shouldNotBeAbleToSendAfterUsingUpYourWindow() { final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); sender.doWork(); assertThat(receivedFrames.size(), is(2)); receivedFrames.remove(); // skip setup dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.streamId(), is(STREAM_ID)); assertThat(dataHeader.sessionId(), is(SESSION_ID)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(dataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(0)); }
@Test public void shouldBeAbleToSendOnChannel() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(2)); setupHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP)); dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.streamId(), is(STREAM_ID)); assertThat(dataHeader.sessionId(), is(SESSION_ID)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(dataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); }
when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH);
when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(2 * ALIGNED_FRAME_LENGTH);
assertThat(statusHeader.streamId(), is(STREAM_ID)); assertThat(statusHeader.sessionId(), is(SESSION_ID)); assertThat(statusHeader.consumptionTermId(), is(ACTIVE_TERM_ID)); assertThat(statusHeader.frameLength(), is(StatusMessageFlyweight.HEADER_LENGTH));
when(msg.consumptionTermId()).thenReturn(termId); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(10);
.streamId(STREAM_ID) .sessionId(SESSION_ID) .consumptionTermId(TERM_ID) .receiverWindowLength(1000) .consumptionTermOffset(0)
public void sendSetupElicitingStatusMessage( final int transportIndex, final InetSocketAddress controlAddress, final int sessionId, final int streamId) { if (!isClosed) { smBuffer.clear(); statusMessageFlyweight .sessionId(sessionId) .streamId(streamId) .consumptionTermId(0) .consumptionTermOffset(0) .receiverWindowLength(0) .flags(SEND_SETUP_FLAG); send(smBuffer, StatusMessageFlyweight.HEADER_LENGTH, transportIndex, controlAddress); } }