1

再生wsクライアントでタイムアウト例外を処理するにはどうすればよいですか? RequestTimeoutとプロセスストリームを指定すると、例外があってもCompletionStageが正常終了します。Play Frameworkのハンドル要求のタイムアウト

例を参照してください。 (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.TimeoutExceptiono.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 

答えて

0

Play 1.2ではタイムアウト例外に直面していました。これは、APIが応答を返すために長い時間がかかっていたからです。問題を解決したタイムアウトを手動で設定することができました。

WSRequest request = WS.url(your_url).timeout("600s"); 
+2

詳細はわかりませんが、動作しません。私は可能な限りすべてのタイムアウトを設定しましたが、例外は低レベルでスローされ、それを傍受する方法はありませんでした。私はApache Async Http Clientを使って直接呼びました。そこで例外ハンドラをオーバーライドする方法があります。 – Tigran

関連する問題