use of com.datastax.oss.protocol.internal.Frame in project java-driver by datastax.
the class SegmentToFrameDecoder method decodeSlice.
private void decodeSlice(Segment<ByteBuf> segment, ByteBufAllocator allocator, List<Object> out) {
assert targetLength != UNKNOWN_LENGTH ^ (accumulatedSlices.isEmpty() && accumulatedLength == 0);
ByteBuf slice = segment.payload;
if (targetLength == UNKNOWN_LENGTH) {
// First slice, read ahead to find the target length
targetLength = FrameCodec.V3_ENCODED_HEADER_SIZE + frameCodec.decodeBodySize(slice);
}
accumulatedSlices.add(slice);
accumulatedLength += slice.readableBytes();
int accumulatedSlicesSize = accumulatedSlices.size();
LOG.trace("[{}] Decoded slice {}, {}/{} bytes", logPrefix, accumulatedSlicesSize, accumulatedLength, targetLength);
assert accumulatedLength <= targetLength;
if (accumulatedLength == targetLength) {
// We've received enough data to reassemble the whole message
CompositeByteBuf encodedFrame = allocator.compositeBuffer(accumulatedSlicesSize);
encodedFrame.addComponents(true, accumulatedSlices);
Frame frame;
try {
frame = frameCodec.decode(encodedFrame);
} finally {
encodedFrame.release();
// Reset our state
targetLength = UNKNOWN_LENGTH;
accumulatedSlices.clear();
accumulatedLength = 0;
}
LOG.trace("[{}] Decoded response frame {} from {} slices", logPrefix, frame.streamId, accumulatedSlicesSize);
out.add(frame);
}
}
use of com.datastax.oss.protocol.internal.Frame in project java-driver by datastax.
the class DriverChannelTest method should_wait_for_coalesced_writes_when_closing_forcefully.
/**
* Ensures that the potential delay introduced by the write coalescer does not mess with the
* forceful shutdown sequence: any write submitted before {@link DriverChannel#forceClose()}
* should get the "Channel was force-closed" error, whether it had been flushed or not.
*/
@Test
public void should_wait_for_coalesced_writes_when_closing_forcefully() {
// Given
MockResponseCallback responseCallback = new MockResponseCallback();
driverChannel.write(new Query("test"), false, Frame.NO_PAYLOAD, responseCallback);
// nothing written yet because the coalescer hasn't flushed
assertNoOutboundFrame();
// When
Future<java.lang.Void> closeFuture = driverChannel.forceClose();
// Then
// not closed yet because there is still a pending write
assertThat(closeFuture).isNotDone();
assertNoOutboundFrame();
// When
// the coalescer finally runs
writeCoalescer.triggerFlush();
// and the pending write goes through
Frame requestFrame = readOutboundFrame();
assertThat(requestFrame).isNotNull();
// Then
assertThat(closeFuture).isSuccess();
assertThat(responseCallback.getFailure()).isInstanceOf(ClosedConnectionException.class).hasMessageContaining("Channel was force-closed");
}
use of com.datastax.oss.protocol.internal.Frame in project java-driver by datastax.
the class InFlightHandlerTest method should_hold_stream_id_for_multi_response_callback.
@Test
public void should_hold_stream_id_for_multi_response_callback() {
// Given
addToPipeline();
when(streamIds.acquire()).thenReturn(42);
MockResponseCallback responseCallback = new MockResponseCallback(frame -> frame.message instanceof Error);
// When
channel.writeAndFlush(new DriverChannel.RequestMessage(QUERY, false, Frame.NO_PAYLOAD, responseCallback)).awaitUninterruptibly();
// Then
// notify callback of stream id
assertThat(responseCallback.streamId).isEqualTo(42);
Frame requestFrame = readOutboundFrame();
for (int i = 0; i < 5; i++) {
// When
// completing pending request
Frame responseFrame = buildInboundFrame(requestFrame, Void.INSTANCE);
writeInboundFrame(responseFrame);
// Then
assertThat(responseCallback.getLastResponse()).isSameAs(responseFrame);
// Stream id not released, callback can receive more responses
verify(streamIds, never()).release(42);
}
// When
// a terminal response comes in
Frame responseFrame = buildInboundFrame(requestFrame, new Error(0, "test"));
writeInboundFrame(responseFrame);
// Then
verify(streamIds).release(42);
assertThat(responseCallback.getLastResponse()).isSameAs(responseFrame);
// When
// more responses come in
writeInboundFrame(requestFrame, Void.INSTANCE);
// Then
// the callback does not get them anymore (this could only be responses to a new request that
// reused the id)
assertThat(responseCallback.getLastResponse()).isNull();
}
use of com.datastax.oss.protocol.internal.Frame in project java-driver by datastax.
the class InFlightHandlerTest method should_notify_callback_of_events.
@Test
public void should_notify_callback_of_events() {
// Given
EventCallback eventCallback = mock(EventCallback.class);
addToPipelineWithEventCallback(eventCallback);
// When
StatusChangeEvent event = new StatusChangeEvent(ProtocolConstants.StatusChangeType.UP, new InetSocketAddress("127.0.0.1", 9042));
Frame eventFrame = Frame.forResponse(DefaultProtocolVersion.V3.getCode(), -1, null, Collections.emptyMap(), Collections.emptyList(), event);
writeInboundFrame(eventFrame);
// Then
ArgumentCaptor<StatusChangeEvent> captor = ArgumentCaptor.forClass(StatusChangeEvent.class);
verify(eventCallback).onEvent(captor.capture());
assertThat(captor.getValue()).isSameAs(event);
}
use of com.datastax.oss.protocol.internal.Frame in project java-driver by datastax.
the class InFlightHandlerTest method should_delay_graceful_close_and_complete_when_last_pending_completes.
@Test
public void should_delay_graceful_close_and_complete_when_last_pending_completes() {
// Given
addToPipeline();
when(streamIds.acquire()).thenReturn(42);
MockResponseCallback responseCallback = new MockResponseCallback();
channel.writeAndFlush(new DriverChannel.RequestMessage(QUERY, false, Frame.NO_PAYLOAD, responseCallback)).awaitUninterruptibly();
// When
channel.write(DriverChannel.GRACEFUL_CLOSE_MESSAGE);
// Then
// not closed yet because there is one pending request
assertThat(channel.closeFuture()).isNotDone();
// When
// completing pending request
Frame requestFrame = readOutboundFrame();
writeInboundFrame(requestFrame, Void.INSTANCE);
// Then
assertThat(channel.closeFuture()).isSuccess();
}
Aggregations