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);
}
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();
}
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);
}
}
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);
}
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);
}
Aggregations