@Test public void testClientIsValid() { StreamIdSupplier s = StreamIdSupplier.clientSupplier(); assertFalse(s.isBeforeOrCurrent(1)); assertFalse(s.isBeforeOrCurrent(3)); s.nextStreamId(); assertTrue(s.isBeforeOrCurrent(1)); assertFalse(s.isBeforeOrCurrent(3)); s.nextStreamId(); assertTrue(s.isBeforeOrCurrent(3)); // negative assertFalse(s.isBeforeOrCurrent(-1)); // connection assertFalse(s.isBeforeOrCurrent(0)); // server also accepted (checked externally) assertTrue(s.isBeforeOrCurrent(2)); }
@Test public void testServerIsValid() { StreamIdSupplier s = StreamIdSupplier.serverSupplier(); assertFalse(s.isBeforeOrCurrent(2)); assertFalse(s.isBeforeOrCurrent(4)); s.nextStreamId(); assertTrue(s.isBeforeOrCurrent(2)); assertFalse(s.isBeforeOrCurrent(4)); s.nextStreamId(); assertTrue(s.isBeforeOrCurrent(4)); // negative assertFalse(s.isBeforeOrCurrent(-2)); // connection assertFalse(s.isBeforeOrCurrent(0)); // client also accepted (checked externally) assertTrue(s.isBeforeOrCurrent(1)); } }
static StreamIdSupplier clientSupplier() { return new StreamIdSupplier(-1); }
@Test public void testServerSequence() { StreamIdSupplier s = StreamIdSupplier.serverSupplier(); assertEquals(2, s.nextStreamId()); assertEquals(4, s.nextStreamId()); assertEquals(6, s.nextStreamId()); }
@Test public void testClientSequence() { StreamIdSupplier s = StreamIdSupplier.clientSupplier(); assertEquals(1, s.nextStreamId()); assertEquals(3, s.nextStreamId()); assertEquals(5, s.nextStreamId()); }
private Mono<Void> handleFireAndForget(Payload payload) { return lifecycle .active() .then( Mono.fromRunnable( () -> { final int streamId = streamIdSupplier.nextStreamId(); final Frame requestFrame = Frame.Request.from(streamId, FrameType.REQUEST_FNF, payload, 1); payload.release(); sendProcessor.onNext(requestFrame); })); }
frameDecoder, errorConsumer, StreamIdSupplier.clientSupplier(), tickPeriod, ackTimeout,
private void handleMissingResponseProcessor(int streamId, FrameType type, Frame frame) { if (!streamIdSupplier.isBeforeOrCurrent(streamId)) { if (type == FrameType.ERROR) { // message for stream that has never existed, we have a problem with // the overall connection and must tear down String errorMessage = frame.getDataUtf8(); throw new IllegalStateException( "Client received error for non-existent stream: " + streamId + " Message: " + errorMessage); } else { throw new IllegalStateException( "Client received message for non-existent stream: " + streamId + ", frame type: " + type); } } // receiving a frame after a given stream has been cancelled/completed, // so ignore (cancellation is async so there is a race condition) }
frameDecoder, errorConsumer, StreamIdSupplier.serverSupplier());
private Mono<Payload> handleRequestResponse(final Payload payload) { return lifecycle .active() .then( Mono.defer( () -> { int streamId = streamIdSupplier.nextStreamId(); final Frame requestFrame = Frame.Request.from(streamId, FrameType.REQUEST_RESPONSE, payload, 1); payload.release(); UnicastMonoProcessor<Payload> receiver = UnicastMonoProcessor.create(); receivers.put(streamId, receiver); sendProcessor.onNext(requestFrame); return receiver .doOnError(t -> sendProcessor.onNext(Frame.Error.from(streamId, t))) .doFinally( s -> { if (s == SignalType.CANCEL) { sendProcessor.onNext(Frame.Cancel.from(streamId)); } receivers.remove(streamId); }); })); }
static Supplier<TestData> requester(int tickPeriod, int timeout, int missedAcks) { return () -> { TestDuplexConnection connection = new TestDuplexConnection(); Errors errors = new Errors(); RSocketClient rSocket = new RSocketClient( connection, DefaultPayload::create, errors, StreamIdSupplier.clientSupplier(), Duration.ofMillis(tickPeriod), Duration.ofMillis(timeout), missedAcks); return new TestData(rSocket, errors, connection); }; }
private void handleMissingResponseProcessor(int streamId, FrameType type, Frame frame) { if (!streamIdSupplier.isBeforeOrCurrent(streamId)) { if (type == FrameType.ERROR) { // message for stream that has never existed, we have a problem with // the overall connection and must tear down String errorMessage = frame.getDataUtf8(); throw new IllegalStateException( "Client received error for non-existent stream: " + streamId + " Message: " + errorMessage); } else { throw new IllegalStateException( "Client received message for non-existent stream: " + streamId + ", frame type: " + type); } } // receiving a frame after a given stream has been cancelled/completed, // so ignore (cancellation is async so there is a race condition) }
frameDecoder, errorConsumer, StreamIdSupplier.serverSupplier());
() -> { final UnicastProcessor<Payload> receiver = UnicastProcessor.create(); final int streamId = streamIdSupplier.nextStreamId(); final AtomicBoolean firstRequest = new AtomicBoolean(true);
@Test void requesterStreamsTerminatedOnZeroErrorFrame() { TestDuplexConnection conn = new TestDuplexConnection(); List<Throwable> errors = new ArrayList<>(); RSocketClient rSocket = new RSocketClient( conn, DefaultPayload::create, errors::add, StreamIdSupplier.clientSupplier()); String errorMsg = "error"; Mono.delay(Duration.ofMillis(100)) .doOnTerminate( () -> conn.addToReceivedBuffer(Frame.Error.from(0, new RejectedSetupException(errorMsg)))) .subscribe(); StepVerifier.create(rSocket.requestResponse(DefaultPayload.create("test"))) .expectErrorMatches( err -> err instanceof RejectedSetupException && errorMsg.equals(err.getMessage())) .verify(Duration.ofSeconds(5)); assertThat(errors).hasSize(1); assertThat(rSocket.isDisposed()).isTrue(); }
static StreamIdSupplier serverSupplier() { return new StreamIdSupplier(0); }
Flux.defer( () -> { int streamId = streamIdSupplier.nextStreamId();
@Test void requesterNewStreamsTerminatedAfterZeroErrorFrame() { TestDuplexConnection conn = new TestDuplexConnection(); RSocketClient rSocket = new RSocketClient( conn, DefaultPayload::create, err -> {}, StreamIdSupplier.clientSupplier()); conn.addToReceivedBuffer(Frame.Error.from(0, new RejectedSetupException("error"))); StepVerifier.create( rSocket .requestResponse(DefaultPayload.create("test")) .delaySubscription(Duration.ofMillis(100))) .expectErrorMatches( err -> err instanceof RejectedSetupException && "error".equals(err.getMessage())) .verify(Duration.ofSeconds(5)); }
static StreamIdSupplier clientSupplier() { return new StreamIdSupplier(-1); }
private Mono<Void> handleFireAndForget(Payload payload) { return lifecycle .active() .then( Mono.fromRunnable( () -> { final int streamId = streamIdSupplier.nextStreamId(); final Frame requestFrame = Frame.Request.from(streamId, FrameType.REQUEST_FNF, payload, 1); payload.release(); sendProcessor.onNext(requestFrame); })); }