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
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 ListenableFuture makeTimeoutFuture(
ListenableFuture 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);