播放框架句柄请求超时
问题描述:
如何在播放ws客户端中处理超时异常?当我指定RequestTimeout
和过程流时,即使有异常,CompletionStage
也会成功完成。播放框架句柄请求超时
查看下面的示例。
代码(从here拍摄):
// Make the request, which should timeout
CompletionStage<StreamedResponse> futureResponse = ws.url("https://download.docker.com/mac/stable/Docker.dmg")
.setMethod("GET").setRequestTimeout(1000)
.stream();
CompletionStage<Long> bytesReturned = futureResponse.thenCompose(res -> {
Source<ByteString, ?> responseBody = res.getBody();
// Count the number of bytes returned
Sink<ByteString, CompletionStage<Long>> bytesSum = Sink.fold(0L, (total, bytes) ->
{
long len = bytes.toArray().length;
return total + len;
});
return responseBody.runWith(bytesSum, materializer);
}).handle((res, err) -> {
LOGGER.info("Res = {}, err = {}", res, err);
return 200L;
}).exceptionally(ex -> {
LOGGER.error("See exception");
return 100L;
});
try {
bytesReturned.toCompletableFuture().get();
LOGGER.info("Got response");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LOGGER.error("Step completed");
我看到在java.util.concurrent.TimeoutException
和o.a.netty.timeout.TimeoutTimerTask
抛出日志,但futureResponse
成功完成。有什么方法可以捕捉到这个错误?
我的问题是,我试图通过控制器将该响应返回给用户,并且因为并非所有数据都被传输而简单地挂起。
[debug] i.n.u.i.JavassistTypeParameterMatcherGenerator - Generated: io.netty.util.internal.__matchers__.org.asynchttpclient.HttpResponseBodyPartMatcher
[debug] o.a.netty.channel.DefaultChannelPool - Closed 0 connections out of 0 in 0 ms
[debug] o.a.netty.timeout.TimeoutTimerTask - Request timeout to download.docker.com/52.84.239.124:443 after 1000 ms for NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHa[email protected]376665d1,
[email protected]9d4d,
[email protected][Not completed],
uri=https://download.docker.com/mac/stable/Docker.dmg,
keepAlive=true,
redirectCount=0,
[email protected]789c9776,
inAuth=0,
statusReceived=1,
touch=1491606083196} after 1075 ms
[debug] o.a.netty.channel.ChannelManager - Closing Channel [id: 0x66ec6bbd, L:/10.155.124.116:52337 - R:download.docker.com/52.84.239.124:443]
[debug] o.a.netty.request.NettyRequestSender - Aborting Future NettyResponseFuture{currentRetry=0,
isDone=0,
isCancelled=0,
asyncHa[email protected]376665d1,
[email protected]9d4d,
[email protected][Not completed],
uri=https://download.docker.com/mac/stable/Docker.dmg,
keepAlive=true,
redirectCount=0,
[email protected]789c9776,
inAuth=0,
statusReceived=1,
touch=1491606083196}
[debug] o.a.netty.request.NettyRequestSender - Request timeout to download.docker.com/52.84.239.124:443 after 1000 ms
java.util.concurrent.TimeoutException: Request timeout to download.docker.com/52.84.239.124:443 after 1000 ms
at org.asynchttpclient.netty.timeout.TimeoutTimerTask.expire(TimeoutTimerTask.java:43)
at org.asynchttpclient.netty.timeout.RequestTimeoutTimerTask.run(RequestTimeoutTimerTask.java:48)
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:588)
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:662)
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:385)
at java.lang.Thread.run(Thread.java:745)
[debug] o.a.netty.handler.HttpHandler - Channel Closed: [id: 0x66ec6bbd, L:/10.155.124.116:52337 ! R:download.docker.com/52.84.239.124:443] with attribute INSTANCE
[info] controllers.RedirectController - Res = 2556824, err = null
[info] controllers.RedirectController - Got response
[error] controllers.RedirectController - Step completed
答
即使我在Play 1.2中面临超时异常,因为api花了很长时间才发回应答。我能够手动设置超时解决了我的问题。
WSRequest request = WS.url(your_url).timeout("600s");
我不记得详细信息,但那是行不通的。我已经在那里设置了所有可能的超时时间,但是会在较低的级别抛出异常,并且我没有办法截取它。我完成了我直接调用的Apache Async Http Client。有一种方法可以覆盖那里的异常处理程序。 – Tigran