0

I am trying to get the result from my CompletableFuture based on different timeouts. The second call to the CompletableFuture would ideally be fire and forget.

Example:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
  try {
     TimeUnit.Seconds.sleep(10);
     return "success"
      
  } catch (InterruptedException e) {
      return "fail";
  }
}

public String method(CompletableFuture<String> future) {
   try {
      return future.get(1, TimeUnit.SECONDS);
   } catch (Exception e) {
      ExecutorService.execute(() -> {
         String result = future.get(10, TimeUnit.SECONDS);
     }
   }

   return "Initial Future timed out"
}

I still would want the Initial Future timed out string to be returned, just another thread to reprocess in a fire and forget way. Addionally, is there a cleaner way of doing something like this. Maybe being able to wrap it all inside the initial CompletableFuture?

Teddy Dong
  • 362
  • 1
  • 6
  • 20
  • What about `CompletionStage#exceptionally()`? – dan1st Jul 01 '21 at 22:27
  • @dan1st would that still work if I need to use ```get``` to try and get the initial value? – Teddy Dong Jul 02 '21 at 01:14
  • I think I would need some threadscheduler to hav the timeout set within thefuture – Teddy Dong Jul 02 '21 at 17:00
  • I've read your question a few times and still can't understand it. Are you passing `future` to `method` in your example? I think you are trying to say that you have a Future and two different timeouts on it calling `get`. You want to do something based on failure of those two ... but even my understanding is vague – Eugene Jul 03 '21 at 02:38
  • Essentially I have one future, but I want to first try to get with an initial timeout and if it fails try to retrieve the future again (in a fire and forget way). Question was if the above was correct in doing so? Is it possible that when I call the future a second time, it has already completed or the wait time is shorting since some of the thread was blocked from the first get? – Teddy Dong Jul 03 '21 at 05:40
  • the other question you had should already answer this one, no? the let's say the total execution of `supplyAsync` currently takes 10 seconds. you first timeout is set for 1 second only - so it fails; the second one is set to 10 seconds, so after 9 seconds, it will succeed. does this make sense? also, you need to tag me with `@` so that I know you posted a comment, otherwise I get no notification. – Eugene Jul 03 '21 at 16:55
  • @Eugene I see. So essentially for CompletableFutures they may start even without calling get so the time to process is different each time? – Teddy Dong Jul 03 '21 at 19:34
  • [yes, exactly](https://stackoverflow.com/questions/65605550/why-does-this-completablefuture-work-even-when-i-dont-call-get-or-join/65606195#65606195) – Eugene Jul 03 '21 at 19:36
  • @Eugene. Thanks, Is there a way to set a timeout on the CompletableFuture itself so that if it does not complete in X amount of time. For example the CompletableFuture takes 5seconds to complete, but it should throw a timeout exception if it doesnt finish within 2 seconds? – Teddy Dong Jul 03 '21 at 19:40
  • `CompletableFuture::orTimeout`, but be careful, as this will not _cancel_ the future, just set the result in the resulting `CompletableFuture`. There is no way to cancel an ongoing future. – Eugene Jul 03 '21 at 19:44
  • @Eugene. Ah that's only in Java 9, guess Java 8 does not have that functionality yet but is what I am looking for thanks! In that case I can reuse the ongoing future in another result . – Teddy Dong Jul 03 '21 at 19:46

0 Answers0