Search in sources :

Example 51 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class HttpClientFactory method getRawClient.

TransportClient getRawClient(Map<String, ? extends Object> properties, SSLContext sslContext, SSLParameters sslParameters) {
    // key which identifies and contains the set of transport properties to create a channel pool manager
    ChannelPoolManagerKey key = createChannelPoolManagerKey(properties, null, null);
    ChannelPoolManagerKey sslKey = createChannelPoolManagerKey(properties, sslContext, sslParameters);
    // Raw Client properties
    int shutdownTimeout = chooseNewOverDefault(getIntValue(properties, HTTP_SHUTDOWN_TIMEOUT), DEFAULT_SHUTDOWN_TIMEOUT);
    int requestTimeout = chooseNewOverDefault(getIntValue(properties, HTTP_REQUEST_TIMEOUT), DEFAULT_REQUEST_TIMEOUT);
    int streamingTimeout = chooseNewOverDefault(getIntValue(properties, HTTP_STREAMING_TIMEOUT), DEFAULT_STREAMING_TIMEOUT);
    if (streamingTimeout > DEFAULT_STREAMING_TIMEOUT) {
        // Minimum value for idle timeout so we don't have a busy thread checking for idle timeout too frequently!
        if (streamingTimeout < DEFAULT_MINIMUM_STREAMING_TIMEOUT) {
            streamingTimeout = DEFAULT_MINIMUM_STREAMING_TIMEOUT;
            LOG.warn("Streaming timeout is too small, resetting to the minimum allowed timeout value of {}ms", DEFAULT_MINIMUM_STREAMING_TIMEOUT);
        }
    }
    String httpServiceName = (String) properties.get(HTTP_SERVICE_NAME);
    HttpProtocolVersion httpProtocolVersion = chooseNewOverDefault(getHttpProtocolVersion(properties, HTTP_PROTOCOL_VERSION), _defaultHttpVersion);
    LOG.info("The service '{}' has been assigned to the ChannelPoolManager with key '{}', http.protocolVersion={}, usePipelineV2={}, requestTimeout={}ms, streamingTimeout={}ms", httpServiceName, key.getName(), httpProtocolVersion, _usePipelineV2, requestTimeout, streamingTimeout);
    if (_usePipelineV2) {
        ChannelPoolManager channelPoolManager;
        ChannelPoolManager sslChannelPoolManager;
        switch(httpProtocolVersion) {
            case HTTP_1_1:
                channelPoolManager = _channelPoolManagerFactory.buildStream(key);
                sslChannelPoolManager = _channelPoolManagerFactory.buildStream(sslKey);
                break;
            case HTTP_2:
                channelPoolManager = _channelPoolManagerFactory.buildHttp2Stream(key);
                sslChannelPoolManager = _channelPoolManagerFactory.buildHttp2Stream(sslKey);
                break;
            default:
                throw new IllegalArgumentException("Unrecognized HTTP protocol version " + httpProtocolVersion);
        }
        return new com.linkedin.r2.netty.client.HttpNettyClient(_eventLoopGroup, _executor, _callbackExecutorGroup, channelPoolManager, sslChannelPoolManager, httpProtocolVersion, SystemClock.instance(), requestTimeout, streamingTimeout, shutdownTimeout);
    }
    TransportClient streamClient;
    switch(httpProtocolVersion) {
        case HTTP_1_1:
            streamClient = new HttpNettyStreamClient(_eventLoopGroup, _executor, requestTimeout, shutdownTimeout, _callbackExecutorGroup, _jmxManager, _channelPoolManagerFactory.buildStream(key), _channelPoolManagerFactory.buildStream(sslKey));
            break;
        case HTTP_2:
            streamClient = new Http2NettyStreamClient(_eventLoopGroup, _executor, requestTimeout, shutdownTimeout, _callbackExecutorGroup, _jmxManager, _channelPoolManagerFactory.buildHttp2Stream(key), _channelPoolManagerFactory.buildHttp2Stream(sslKey));
            break;
        default:
            throw new IllegalArgumentException("Unrecognized HTTP protocol version " + httpProtocolVersion);
    }
    HttpNettyClient legacyClient = new HttpNettyClient(_eventLoopGroup, _executor, requestTimeout, shutdownTimeout, _callbackExecutorGroup, _jmxManager, _channelPoolManagerFactory.buildRest(key), _channelPoolManagerFactory.buildRest(sslKey));
    return new MixedClient(legacyClient, streamClient);
}
Also used : TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) HttpProtocolVersion(com.linkedin.r2.transport.http.common.HttpProtocolVersion) ChannelPoolManager(com.linkedin.r2.transport.http.client.common.ChannelPoolManager) HttpNettyClient(com.linkedin.r2.transport.http.client.rest.HttpNettyClient) HttpNettyStreamClient(com.linkedin.r2.transport.http.client.stream.http.HttpNettyStreamClient) Http2NettyStreamClient(com.linkedin.r2.transport.http.client.stream.http2.Http2NettyStreamClient) ChannelPoolManagerKey(com.linkedin.r2.transport.http.client.common.ChannelPoolManagerKey)

Example 52 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class TestHttpNettyClient method testShutdownRequestOutstanding.

private void testShutdownRequestOutstanding(int shutdownTimeout, int requestTimeout, Class<?>... causeChain) throws InterruptedException, IOException, ExecutionException, TimeoutException {
    TestServer testServer = new TestServer();
    HttpNettyClient client = new HttpClientBuilder(_eventLoop, _scheduler).setRequestTimeout(requestTimeout).setShutdownTimeout(shutdownTimeout).buildRestClient();
    RestRequest r = new RestRequestBuilder(testServer.getNoResponseURI()).build();
    FutureCallback<RestResponse> cb = new FutureCallback<>();
    TransportCallback<RestResponse> callback = new TransportCallbackAdapter<>(cb);
    client.restRequest(r, new RequestContext(), new HashMap<>(), callback);
    FutureCallback<None> shutdownCallback = new FutureCallback<>();
    client.shutdown(shutdownCallback);
    shutdownCallback.get(30, TimeUnit.SECONDS);
    try {
        // This timeout needs to be significantly larger than the getTimeout of the netty client;
        // we're testing that the client will generate its own timeout
        cb.get(30, TimeUnit.SECONDS);
        Assert.fail("Get was supposed to time out");
    } catch (TimeoutException e) {
        // TimeoutException means the timeout for Future.get() elapsed and nothing happened.
        // Instead, we are expecting our callback to be invoked before the future timeout
        // with a timeout generated by the HttpNettyClient.
        Assert.fail("Get timed out, should have thrown ExecutionException", e);
    } catch (ExecutionException e) {
        verifyCauseChain(e, causeChain);
    }
    testServer.shutdown();
}
Also used : TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter) RestResponse(com.linkedin.r2.message.rest.RestResponse) HttpNettyClient(com.linkedin.r2.transport.http.client.rest.HttpNettyClient) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) ExecutionException(java.util.concurrent.ExecutionException) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) TimeoutException(java.util.concurrent.TimeoutException)

Example 53 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class RAPStreamResponseDecoder method channelRead0.

@Override
protected void channelRead0(final ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    if (msg instanceof HttpResponse) {
        HttpResponse m = (HttpResponse) msg;
        _shouldCloseConnection = !HttpUtil.isKeepAlive(m);
        if (HttpUtil.is100ContinueExpected(m)) {
            ctx.writeAndFlush(CONTINUE).addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        ctx.fireExceptionCaught(future.cause());
                    }
                }
            });
        }
        if (!m.decoderResult().isSuccess()) {
            ctx.fireExceptionCaught(m.decoderResult().cause());
            return;
        }
        // remove chunked encoding.
        if (HttpUtil.isTransferEncodingChunked(m)) {
            HttpUtil.setTransferEncodingChunked(m, false);
        }
        Timeout<None> timeout = ctx.channel().attr(TIMEOUT_ATTR_KEY).getAndSet(null);
        if (timeout == null) {
            LOG.debug("dropped a response after channel inactive or exception had happened.");
            return;
        }
        final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, _maxContentLength, BUFFER_HIGH_WATER_MARK, BUFFER_LOW_WATER_MARK, timeout);
        EntityStream entityStream = EntityStreams.newEntityStream(writer);
        _chunkedMessageWriter = writer;
        // Refactored duplicate code to new code pipeline.
        StreamResponseBuilder builder = HttpMessageDecoders.ResponseDecoder.buildStreamResponse(m);
        ctx.fireChannelRead(builder.build(entityStream));
    } else if (msg instanceof HttpContent) {
        HttpContent chunk = (HttpContent) msg;
        TimeoutBufferedWriter currentWriter = _chunkedMessageWriter;
        // Sanity check
        if (currentWriter == null) {
            throw new IllegalStateException("received " + HttpContent.class.getSimpleName() + " without " + HttpResponse.class.getSimpleName());
        }
        if (!chunk.decoderResult().isSuccess()) {
            this.exceptionCaught(ctx, chunk.decoderResult().cause());
        }
        currentWriter.processHttpChunk(chunk);
        if (chunk instanceof LastHttpContent) {
            _chunkedMessageWriter = null;
        }
    } else {
        // something must be wrong, but let's proceed so that
        // handler after us has a chance to process it.
        ctx.fireChannelRead(msg);
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) DefaultFullHttpResponse(io.netty.handler.codec.http.DefaultFullHttpResponse) HttpResponse(io.netty.handler.codec.http.HttpResponse) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) ChannelFutureListener(io.netty.channel.ChannelFutureListener) TimeoutException(java.util.concurrent.TimeoutException) ClosedChannelException(java.nio.channels.ClosedChannelException) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) TooLongFrameException(io.netty.handler.codec.TooLongFrameException) IOException(java.io.IOException) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) None(com.linkedin.common.util.None) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent)

Example 54 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class ChannelPoolManagerImpl method shutdown.

public void shutdown(final Callback<None> callback, final Runnable callbackStopRequest, final Runnable callbackShutdown, long shutdownTimeout) {
    final long deadline = System.currentTimeMillis() + shutdownTimeout;
    Callback<None> closeChannels = new TimeoutCallback<>(_scheduler, shutdownTimeout, TimeUnit.MILLISECONDS, new Callback<None>() {

        private void finishShutdown() {
            callbackStopRequest.run();
            // Timeout any waiters which haven't received a Channel yet
            cancelWaiters();
            // Close all active and idle Channels
            final TimeoutRunnable afterClose = new TimeoutRunnable(_scheduler, deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS, () -> {
                callbackShutdown.run();
                LOG.info("Shutdown complete");
                callback.onSuccess(None.none());
            }, "Timed out waiting for channels to close, continuing shutdown");
            _allChannels.close().addListener((ChannelGroupFutureListener) channelGroupFuture -> {
                if (!channelGroupFuture.isSuccess()) {
                    LOG.warn("Failed to close some connections, ignoring");
                }
                afterClose.run();
            });
        }

        @Override
        public void onSuccess(None none) {
            LOG.info("All connection pools shut down, closing all channels");
            finishShutdown();
        }

        @Override
        public void onError(Throwable e) {
            LOG.warn("Error shutting down HTTP connection pools, ignoring and continuing shutdown", e);
            finishShutdown();
        }
    }, "Connection pool shutdown timeout exceeded");
    shutdownPool(closeChannels);
}
Also used : TimeoutRunnable(com.linkedin.r2.util.TimeoutRunnable) ChannelGroupFutureListener(io.netty.channel.group.ChannelGroupFutureListener) None(com.linkedin.common.util.None) TimeoutCallback(com.linkedin.r2.transport.http.client.TimeoutCallback)

Example 55 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class TestRestLiMethodInvocation method testTimeoutParseqTraceTask.

@Test(dataProvider = "taskMethodConfigProviders")
public void testTimeoutParseqTraceTask(RestLiMethodConfig restliMethodConfig, String timeoutTaskName) throws Exception {
    Map<String, ResourceModel> resourceModelMap = buildResourceModels(TaskStatusCollectionResource.class);
    ResourceModel taskStatusResourceModel = resourceModelMap.get("/taskstatuses");
    // #4: Task based Async Method Execution
    RequestContext taskRequestContext = new RequestContext();
    ResourceMethodDescriptor methodDescriptor = taskStatusResourceModel.findMethod(ResourceMethod.GET);
    TaskStatusCollectionResource taskStatusResource = getMockResource(TaskStatusCollectionResource.class);
    EasyMock.expect(taskStatusResource.get(eq(1L))).andReturn(Task.callable("myTask", new Callable<Status>() {

        @Override
        public Status call() throws Exception {
            return new Status();
        }
    })).once();
    // configure method-level timeout
    ResourceMethodConfigProvider methodConfigProvider = ResourceMethodConfigProvider.build(restliMethodConfig);
    ResourceMethodConfig methodConfig = methodConfigProvider.apply(methodDescriptor);
    checkInvocation(taskStatusResource, taskRequestContext, methodDescriptor, methodConfig, "GET", version, "/taskstatuses/1", null, buildPathKeys("statusID", 1L), new Callback<RestResponse>() {

        @Override
        public void onError(Throwable e) {
            Assert.fail("Request failed unexpectedly.");
        }

        @Override
        public void onSuccess(RestResponse result) {
            Trace parseqTrace = (Trace) taskRequestContext.getLocalAttr(ATTRIBUTE_PARSEQ_TRACE);
            Assert.assertNotNull(parseqTrace);
            if (timeoutTaskName != null) {
                Assert.assertTrue(hasTask(timeoutTaskName, parseqTrace));
            }
        }
    }, true, false, null, null);
}
Also used : Status(com.linkedin.restli.server.twitter.TwitterTestDataModels.Status) HttpStatus(com.linkedin.restli.common.HttpStatus) TaskStatusCollectionResource(com.linkedin.restli.server.twitter.TaskStatusCollectionResource) RestResponse(com.linkedin.r2.message.rest.RestResponse) ResourceMethodDescriptor(com.linkedin.restli.internal.server.model.ResourceMethodDescriptor) ByteString(com.linkedin.data.ByteString) CustomString(com.linkedin.restli.server.custom.types.CustomString) RestException(com.linkedin.r2.message.rest.RestException) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RoutingException(com.linkedin.restli.server.RoutingException) RestLiSyntaxException(com.linkedin.restli.internal.server.util.RestLiSyntaxException) ResourceMethodConfigProvider(com.linkedin.restli.server.config.ResourceMethodConfigProvider) Trace(com.linkedin.parseq.trace.Trace) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) RestLiTestHelper.buildResourceModel(com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel) ResourceMethodConfig(com.linkedin.restli.server.config.ResourceMethodConfig) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Aggregations

Test (org.testng.annotations.Test)78 RequestContext (com.linkedin.r2.message.RequestContext)46 CountDownLatch (java.util.concurrent.CountDownLatch)40 TimeoutException (java.util.concurrent.TimeoutException)40 None (com.linkedin.common.util.None)33 FutureCallback (com.linkedin.common.callback.FutureCallback)32 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)26 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)25 URI (java.net.URI)25 RestRequest (com.linkedin.r2.message.rest.RestRequest)21 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)21 ByteString (com.linkedin.data.ByteString)19 HashMap (java.util.HashMap)19 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)19 RestResponse (com.linkedin.r2.message.rest.RestResponse)18 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)17 ExecutionException (java.util.concurrent.ExecutionException)17 TransportClient (com.linkedin.r2.transport.common.bridge.client.TransportClient)15 IOException (java.io.IOException)15 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)13