code: public static <T> ListenableFuture<T> addTimeout(ListenableFuture<T> future, Callable<T> onTimeout, Duration timeout, ScheduledExecutorService executorService)
      {
          AsyncFunction<TimeoutException, T> timeoutHandler = timeoutException -> {
              try {
                  return immediateFuture(onTimeout.call());
              }
              catch (Throwable throwable) {
                  return immediateFailedFuture(throwable);
              }
          };
          return FluentFuture.from(future)
                  .withTimeout(timeout.toMillis(), MILLISECONDS, executorService)
                  .catchingAsync(TimeoutException.class, timeoutHandler, directExecutor());
      }
docs: Returns a new future that is completed when the supplied future completes or
  when the timeout expires.  If the timeout occurs or the returned CompletableFuture
  is canceled, the supplied future will be canceled.