Search in sources :

Example 1 with StreamedResponsePublisher

use of org.asynchttpclient.netty.handler.StreamedResponsePublisher in project async-http-client by AsyncHttpClient.

the class NettyReactiveStreamsTest method testRetryingOnFailingStream.

@Test(groups = "standalone")
public void testRetryingOnFailingStream() throws Exception {
    try (AsyncHttpClient client = asyncHttpClient()) {
        // allows us to wait until subscriber has received the first body chunk
        final CountDownLatch streamStarted = new CountDownLatch(1);
        // allows us to hold the subscriber from processing further body chunks
        final CountDownLatch streamOnHold = new CountDownLatch(1);
        // allows us to block until the request is being replayed ( this is what we want to test here!)
        final CountDownLatch replayingRequest = new CountDownLatch(1);
        // a ref to the publisher is needed to get a hold on the channel (if there is a better way, this should be changed) 
        final AtomicReference<StreamedResponsePublisher> publisherRef = new AtomicReference<>(null);
        // executing the request
        client.preparePost(getTargetUrl()).setBody(LARGE_IMAGE_BYTES).execute(new ReplayedSimpleAsyncHandler(replayingRequest, new BlockedStreamSubscriber(streamStarted, streamOnHold)) {

            @Override
            public State onStream(Publisher<HttpResponseBodyPart> publisher) {
                if (!(publisher instanceof StreamedResponsePublisher)) {
                    throw new IllegalStateException(String.format("publisher %s is expected to be an instance of %s", publisher, StreamedResponsePublisher.class));
                } else if (!publisherRef.compareAndSet(null, (StreamedResponsePublisher) publisher)) {
                    // abort on retry
                    return State.ABORT;
                }
                return super.onStream(publisher);
            }
        });
        // before proceeding, wait for the subscriber to receive at least one body chunk
        streamStarted.await();
        // The stream has started, hence `StreamedAsyncHandler.onStream(publisher)` was called, and `publisherRef` was initialized with the `publisher` passed to `onStream`
        assertTrue(publisherRef.get() != null, "Expected a not null publisher.");
        // close the channel to emulate a connection crash while the response body chunks were being received.
        StreamedResponsePublisher publisher = publisherRef.get();
        final CountDownLatch channelClosed = new CountDownLatch(1);
        getChannel(publisher).close().addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                channelClosed.countDown();
            }
        });
        // the subscriber is set free to process new incoming body chunks.
        streamOnHold.countDown();
        // the channel is confirmed to be closed
        channelClosed.await();
        // now we expect a new connection to be created and AHC retry logic to kick-in automatically
        // wait until we are notified the request is being replayed
        replayingRequest.await();
        // Change this if there is a better way of stating the test succeeded 
        assertTrue(true);
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) StreamedResponsePublisher(org.asynchttpclient.netty.handler.StreamedResponsePublisher) HttpResponseBodyPart(org.asynchttpclient.HttpResponseBodyPart) AsyncHttpClient(org.asynchttpclient.AsyncHttpClient) Test(org.testng.annotations.Test) ReactiveStreamsTest(org.asynchttpclient.reactivestreams.ReactiveStreamsTest)

Aggregations

ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelFutureListener (io.netty.channel.ChannelFutureListener)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 AsyncHttpClient (org.asynchttpclient.AsyncHttpClient)1 HttpResponseBodyPart (org.asynchttpclient.HttpResponseBodyPart)1 StreamedResponsePublisher (org.asynchttpclient.netty.handler.StreamedResponsePublisher)1 ReactiveStreamsTest (org.asynchttpclient.reactivestreams.ReactiveStreamsTest)1 Test (org.testng.annotations.Test)1