ListenableFuture, FutureCallback and timeouts

后端 未结 1 367
滥情空心
滥情空心 2021-01-31 15:51

Based on the examples of guava I\'ve seen I\'ve been looking for elegant solutions to my problem. Specifically, I like the way Futures.addCallback(ListenableFuture, FutureCallba

相关标签:
1条回答
  • 2021-01-31 16:20

    Update: This has been added to Guava as Futures.withTimeout().


    Internally, we have a makeTimeoutFuture method that takes a Future as input and returns a new Future that will have the same result unless the original hasn't completed by a given deadline. If the deadline expires, the output Future has its result set to a TimeoutException. So, you could call makeTimeoutFuture and attach listeners to the output Future.

    makeTimeoutFuture isn't the most natural solution for your problem. In fact, I think that the method was created primarily to set a hard timeout on no-arg get() calls, since it can be a pain to propagate the desired deadline to all callers. A more natural solution is to reason that get() is to get(long, TimeUnit) as addCallback(ListenableFuture, FutureCallback) is to addCallback(ListenableFuture, FutureCallback, long, TimeUnit, SchededuledExecutorService). That's a little clumsy, albeit less so than makeTimeoutFuture. I'd want to give this more thought before committing to anything. Would you file a feature request?

    (Here's what we have internally:)

    public static <V> ListenableFuture<V> makeTimeoutFuture(
        ListenableFuture<V> delegate,
        Duration duration,
        ScheduledExecutorService scheduledExecutor)
    

    Returns a future that delegates to another but will finish early (via a TimeoutException wrapped in an ExecutionException) if the specified duration expires. The delegate future is not cancelled in this case.

    scheduledExecutor.schedule(new Runnable() {
      @Override public void run() {
        TimeoutFuture.this.setException(new TimeoutException("Future timed out"));
      }
    }, duration.getMillis(), TimeUnit.MILLISECONDS);
    
    0 讨论(0)
提交回复
热议问题