use of io.servicetalk.concurrent.PublisherSource.Subscription in project servicetalk by apple.
the class NettyPipelinedConnectionTest method writeThrowsClosesConnection.
@Test
void writeThrowsClosesConnection() {
TestPublisher<Integer> mockReadPublisher2 = new TestPublisher<>();
@SuppressWarnings("unchecked") NettyConnection<Integer, Integer> mockConnection = mock(NettyConnection.class);
doAnswer((Answer<Publisher<Integer>>) invocation -> mockReadPublisher2).when(mockConnection).read();
doAnswer((Answer<Completable>) invocation -> {
throw DELIBERATE_EXCEPTION;
}).when(mockConnection).write(eq(writePublisher1), any(), any());
doAnswer((Answer<Completable>) invocation -> {
Publisher<Integer> writePub = invocation.getArgument(0);
return writePub.ignoreElements();
}).when(mockConnection).write(eq(writePublisher2), any(), any());
when(mockConnection.closeAsync()).thenReturn(completed());
requester = new NettyPipelinedConnection<>(mockConnection, 2);
toSource(requester.write(writePublisher1)).subscribe(readSubscriber);
toSource(requester.write(writePublisher2)).subscribe(readSubscriber2);
Subscription readSubscription = readSubscriber.awaitSubscription();
readSubscription.request(1);
assertThat(readSubscriber.awaitOnError(), is(DELIBERATE_EXCEPTION));
assertFalse(writePublisher1.isSubscribed());
verify(mockConnection).closeAsync();
}
use of io.servicetalk.concurrent.PublisherSource.Subscription in project servicetalk by apple.
the class NettyPipelinedConnectionTest method readSubscribeThrowsWritesStillProcessed.
@Test
void readSubscribeThrowsWritesStillProcessed() {
AtomicBoolean thrownError = new AtomicBoolean();
Publisher<Integer> mockReadPublisher = new Publisher<Integer>() {
@Override
protected void handleSubscribe(final PublisherSource.Subscriber<? super Integer> subscriber) {
if (thrownError.compareAndSet(false, true)) {
throw DELIBERATE_EXCEPTION;
} else {
deliverCompleteFromSource(subscriber);
}
}
};
@SuppressWarnings("unchecked") NettyConnection<Integer, Integer> mockConnection = mock(NettyConnection.class);
when(mockConnection.read()).thenReturn(mockReadPublisher);
doAnswer((Answer<Completable>) invocation -> {
Publisher<Integer> writePub = invocation.getArgument(0);
return writePub.ignoreElements();
}).when(mockConnection).write(any(), any(), any());
requester = new NettyPipelinedConnection<>(mockConnection, 2);
toSource(requester.write(writePublisher1)).subscribe(readSubscriber);
toSource(requester.write(writePublisher2)).subscribe(readSubscriber2);
Subscription readSubscription = readSubscriber.awaitSubscription();
readSubscription.request(1);
assertTrue(writePublisher1.isSubscribed());
writePublisher1.onError(newSecondException());
assertThat(readSubscriber.awaitOnError(), is(DELIBERATE_EXCEPTION));
readSubscriber2.awaitSubscription();
assertTrue(writePublisher2.isSubscribed());
writePublisher2.onComplete();
readSubscriber2.awaitOnComplete();
verify(mockConnection, never()).closeAsync();
}
use of io.servicetalk.concurrent.PublisherSource.Subscription in project servicetalk by apple.
the class NettyPipelinedConnectionTest method readCancelErrorsPendingReadCancelsPendingWrite.
@Test
void readCancelErrorsPendingReadCancelsPendingWrite() throws Exception {
TestSubscription writePublisher1Subscription = new TestSubscription();
toSource(requester.write(writePublisher1.afterSubscription(() -> writePublisher1Subscription))).subscribe(readSubscriber);
Subscription readSubscription = readSubscriber.awaitSubscription();
readSubscription.request(1);
toSource(requester.write(writePublisher2)).subscribe(readSubscriber2);
assertTrue(writePublisher1.isSubscribed());
// cancelling an active read will close the connection.
readSubscription.cancel();
// readSubscriber was cancelled, so it may or may not terminate, but other sources that have not terminated
// should be terminated, cancelled, or not subscribed.
assertThat(readSubscriber2.awaitOnError(), is(instanceOf(ClosedChannelException.class)));
writePublisher1Subscription.awaitCancelled();
assertFalse(writePublisher2.isSubscribed());
assertFalse(channel.isOpen());
}
use of io.servicetalk.concurrent.PublisherSource.Subscription in project servicetalk by apple.
the class NettyPipelinedConnectionTest method readCancelClosesConnectionThenWriteDoesNotSubscribe.
@Test
void readCancelClosesConnectionThenWriteDoesNotSubscribe() throws Exception {
TestSubscription writePublisher1Subscription = new TestSubscription();
toSource(requester.write(writePublisher1.afterSubscription(() -> writePublisher1Subscription))).subscribe(readSubscriber);
Subscription readSubscription = readSubscriber.awaitSubscription();
readSubscription.request(1);
assertTrue(writePublisher1.isSubscribed());
// cancelling an active read will close the connection.
readSubscription.cancel();
// readSubscriber was cancelled, so it may or may not terminate, but other sources that have not terminated
// should be terminated, cancelled, or not subscribed.
writePublisher1Subscription.awaitCancelled();
assertFalse(channel.isOpen());
toSource(requester.write(writePublisher2)).subscribe(readSubscriber2);
assertThat(readSubscriber2.awaitOnError(), is(instanceOf(ClosedChannelException.class)));
assertFalse(writePublisher2.isSubscribed());
}
use of io.servicetalk.concurrent.PublisherSource.Subscription in project servicetalk by apple.
the class WriteStreamSubscriber method channelOutboundClosed.
@Override
public void channelOutboundClosed() {
assert eventLoop.inEventLoop();
final Subscription sub = this.subscription;
if (sub != null) {
// Some protocols may know the source should terminate before the user is done writing all the content. For
// example if HTTP headers includes content-length: 0, the protocol knows it is done after writing the
// metadata, but the user may have also written empty buffer and/or empty trailers that still need to be
// consumed. If the FlushStrategy waits until the stream terminates we must request the remainder of content
// we may deadlock if we don't request enough onNext signals to see the terminal signal.
sub.request(Long.MAX_VALUE);
}
promise.sourceTerminated(null);
}
Aggregations