Search in sources :

Example 16 with Subscription

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();
}
Also used : UNSUPPORTED_PROTOCOL_CLOSE_HANDLER(io.servicetalk.transport.netty.internal.CloseHandler.UNSUPPORTED_PROTOCOL_CLOSE_HANDLER) BeforeEach(org.junit.jupiter.api.BeforeEach) Protocol(io.servicetalk.transport.api.ConnectionInfo.Protocol) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) MAX_VALUE(java.lang.Integer.MAX_VALUE) Future(java.util.concurrent.Future) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Executor(io.servicetalk.concurrent.api.Executor) Executors.immediate(io.servicetalk.concurrent.api.Executors.immediate) TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) CyclicBarrier(java.util.concurrent.CyclicBarrier) SynchronousQueue(java.util.concurrent.SynchronousQueue) PublisherSource(io.servicetalk.concurrent.PublisherSource) Collection(java.util.Collection) DefaultNettyConnection(io.servicetalk.transport.netty.internal.DefaultNettyConnection) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) Test(org.junit.jupiter.api.Test) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) List(java.util.List) SubscriberUtils.deliverCompleteFromSource(io.servicetalk.concurrent.internal.SubscriberUtils.deliverCompleteFromSource) RetryableException(io.servicetalk.transport.api.RetryableException) WriteDemandEstimators(io.servicetalk.transport.netty.internal.WriteDemandEstimators) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) FlushStrategies.defaultFlushStrategy(io.servicetalk.transport.netty.internal.FlushStrategies.defaultFlushStrategy) Matchers.is(org.hamcrest.Matchers.is) CloseHandler(io.servicetalk.transport.netty.internal.CloseHandler) NoopConnectionObserver(io.servicetalk.transport.netty.internal.NoopTransportObserver.NoopConnectionObserver) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) FlushStrategy(io.servicetalk.transport.netty.internal.FlushStrategy) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) DEFAULT_ALLOCATOR(io.servicetalk.buffer.netty.BufferAllocators.DEFAULT_ALLOCATOR) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) Publisher(io.servicetalk.concurrent.api.Publisher) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Answer(org.mockito.stubbing.Answer) Matchers.hasSize(org.hamcrest.Matchers.hasSize) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) DELIBERATE_EXCEPTION(io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION) ExecutorService(java.util.concurrent.ExecutorService) ClosedChannelException(java.nio.channels.ClosedChannelException) Single(io.servicetalk.concurrent.api.Single) Completable(io.servicetalk.concurrent.api.Completable) EmbeddedDuplexChannel(io.servicetalk.transport.netty.internal.EmbeddedDuplexChannel) Mockito.when(org.mockito.Mockito.when) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) SourceAdapters.toSource(io.servicetalk.concurrent.api.SourceAdapters.toSource) CompletableSource(io.servicetalk.concurrent.CompletableSource) Mockito.verify(org.mockito.Mockito.verify) Mockito.never(org.mockito.Mockito.never) WriteDemandEstimator(io.servicetalk.transport.netty.internal.WriteDemandEstimator) Completable.completed(io.servicetalk.concurrent.api.Completable.completed) Executors(io.servicetalk.concurrent.api.Executors) NettyConnection(io.servicetalk.transport.netty.internal.NettyConnection) SECONDS(java.util.concurrent.TimeUnit.SECONDS) Completable(io.servicetalk.concurrent.api.Completable) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) Publisher(io.servicetalk.concurrent.api.Publisher) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) Test(org.junit.jupiter.api.Test)

Example 17 with Subscription

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();
}
Also used : UNSUPPORTED_PROTOCOL_CLOSE_HANDLER(io.servicetalk.transport.netty.internal.CloseHandler.UNSUPPORTED_PROTOCOL_CLOSE_HANDLER) BeforeEach(org.junit.jupiter.api.BeforeEach) Protocol(io.servicetalk.transport.api.ConnectionInfo.Protocol) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) MAX_VALUE(java.lang.Integer.MAX_VALUE) Future(java.util.concurrent.Future) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Executor(io.servicetalk.concurrent.api.Executor) Executors.immediate(io.servicetalk.concurrent.api.Executors.immediate) TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) CyclicBarrier(java.util.concurrent.CyclicBarrier) SynchronousQueue(java.util.concurrent.SynchronousQueue) PublisherSource(io.servicetalk.concurrent.PublisherSource) Collection(java.util.Collection) DefaultNettyConnection(io.servicetalk.transport.netty.internal.DefaultNettyConnection) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) Test(org.junit.jupiter.api.Test) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) List(java.util.List) SubscriberUtils.deliverCompleteFromSource(io.servicetalk.concurrent.internal.SubscriberUtils.deliverCompleteFromSource) RetryableException(io.servicetalk.transport.api.RetryableException) WriteDemandEstimators(io.servicetalk.transport.netty.internal.WriteDemandEstimators) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) FlushStrategies.defaultFlushStrategy(io.servicetalk.transport.netty.internal.FlushStrategies.defaultFlushStrategy) Matchers.is(org.hamcrest.Matchers.is) CloseHandler(io.servicetalk.transport.netty.internal.CloseHandler) NoopConnectionObserver(io.servicetalk.transport.netty.internal.NoopTransportObserver.NoopConnectionObserver) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) FlushStrategy(io.servicetalk.transport.netty.internal.FlushStrategy) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) DEFAULT_ALLOCATOR(io.servicetalk.buffer.netty.BufferAllocators.DEFAULT_ALLOCATOR) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) Publisher(io.servicetalk.concurrent.api.Publisher) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Answer(org.mockito.stubbing.Answer) Matchers.hasSize(org.hamcrest.Matchers.hasSize) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) DELIBERATE_EXCEPTION(io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION) ExecutorService(java.util.concurrent.ExecutorService) ClosedChannelException(java.nio.channels.ClosedChannelException) Single(io.servicetalk.concurrent.api.Single) Completable(io.servicetalk.concurrent.api.Completable) EmbeddedDuplexChannel(io.servicetalk.transport.netty.internal.EmbeddedDuplexChannel) Mockito.when(org.mockito.Mockito.when) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) SourceAdapters.toSource(io.servicetalk.concurrent.api.SourceAdapters.toSource) CompletableSource(io.servicetalk.concurrent.CompletableSource) Mockito.verify(org.mockito.Mockito.verify) Mockito.never(org.mockito.Mockito.never) WriteDemandEstimator(io.servicetalk.transport.netty.internal.WriteDemandEstimator) Completable.completed(io.servicetalk.concurrent.api.Completable.completed) Executors(io.servicetalk.concurrent.api.Executors) NettyConnection(io.servicetalk.transport.netty.internal.NettyConnection) SECONDS(java.util.concurrent.TimeUnit.SECONDS) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Completable(io.servicetalk.concurrent.api.Completable) TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) Publisher(io.servicetalk.concurrent.api.Publisher) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) Test(org.junit.jupiter.api.Test)

Example 18 with Subscription

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());
}
Also used : TestSubscription(io.servicetalk.concurrent.api.TestSubscription) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) Test(org.junit.jupiter.api.Test)

Example 19 with Subscription

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());
}
Also used : TestSubscription(io.servicetalk.concurrent.api.TestSubscription) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) Test(org.junit.jupiter.api.Test)

Example 20 with Subscription

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);
}
Also used : ConcurrentSubscription(io.servicetalk.concurrent.internal.ConcurrentSubscription) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) EmptySubscriptions.newEmptySubscription(io.servicetalk.concurrent.internal.EmptySubscriptions.newEmptySubscription)

Aggregations

Subscription (io.servicetalk.concurrent.PublisherSource.Subscription)181 Test (org.junit.jupiter.api.Test)107 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)78 CountDownLatch (java.util.concurrent.CountDownLatch)45 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)44 AtomicReference (java.util.concurrent.atomic.AtomicReference)44 TestPublisherSubscriber (io.servicetalk.concurrent.test.internal.TestPublisherSubscriber)38 DELIBERATE_EXCEPTION (io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION)31 Nullable (javax.annotation.Nullable)31 TestSubscription (io.servicetalk.concurrent.api.TestSubscription)30 MethodSource (org.junit.jupiter.params.provider.MethodSource)28 ValueSource (org.junit.jupiter.params.provider.ValueSource)28 PublisherSource (io.servicetalk.concurrent.PublisherSource)27 SourceAdapters.toSource (io.servicetalk.concurrent.api.SourceAdapters.toSource)27 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)27 Matchers.is (org.hamcrest.Matchers.is)27 Subscriber (io.servicetalk.concurrent.PublisherSource.Subscriber)26 CyclicBarrier (java.util.concurrent.CyclicBarrier)25 ExecutorService (java.util.concurrent.ExecutorService)25 Mockito.mock (org.mockito.Mockito.mock)25