0

In our application we are using Java futures to asynchronously retrieve data from an external Redis instance. The Redis library we use using is Lettuce which appears to be using CompletableFuture under-the-hood for its async commands. Ideally we would like to limit these so that queries time out after 500ms - this timeout value is extremely high as our commands typically only take a few ms.

Under high load it is expected that our application may have a GC stop-the-world time of around 1 second.

In this case would the GC pause extend the timeout period, or would it immediately throw a TimeoutException once processing begins again?

curtisjk
  • 1
  • 2
  • 1
    `Future` is an interface. The timeout version of `get` makes no guarantees so it will depend upon the specific implementation of `Future`. – Michael Jan 07 '20 at 15:18
  • @Michael The javadoc says "Waits if necessary for at most the given time" though. Anyway, I doubt any implementation will throw the exception during a stop-the-world GC pause. – marstran Jan 07 '20 at 15:21
  • @marstran "*I doubt any implementation will throw the exception during a stop-the-world GC pause*" **No implementation** will throw anything duration a stop-the-world GC pause. The world is stopped. Nothing can happen. The point is that it will depend at what point the world gets stopped, and when the implementation performs the timeout check after it has resumed – Michael Jan 07 '20 at 15:25
  • @Michael That was my point. An implementation could theoretically cancel _before_ the GC-pause though I'd guess. – marstran Jan 07 '20 at 15:33
  • Apologies - I didn't realise Future was an interface - I've dug a bit further into the Lettuce library and it seems it is using CompletableFuture. I have updated the main post with this information. – curtisjk Jan 07 '20 at 15:50
  • 1
    What kind of timeout are we talking about? A timeout implemented in the lettuce library or a timeout implemented in the `CompletableFuture` (i.e. Java 9 or newer)? These things are not connected. – Holger Jan 07 '20 at 21:49
  • The timeout is the value passed the the Future.get() interface – curtisjk Jan 08 '20 at 13:52
  • In that case it doesn’t matter much a) if the gc happens before the waiting, the timeout is relative to some point of time after the gc, so they add, b) if the gc happens after the waiting, the thread has finished waiting but is stopped for the gc, so the times add, c) if the waiting overlaps with the gc, the waiting may consider the time that has elapsed during the gc, but can’t prevent the time needed for the gc nor the waiting time that has already elapsed before the gc, so the effective time would be between 1 second and 1,5 second (1 s + 500ms). In either case, far away from the 500s goal – Holger Jan 09 '20 at 11:54
  • @Holger not every phase of the GC have to stop everything, some can be concurrent, while giving the application threads a much lower priority for example. – Eugene Jan 09 '20 at 19:53
  • @Eugene that’s right, but the question was specifically about the impact of a “stop-the-world time of around 1 second”. – Holger Jan 09 '20 at 19:55
  • @Holger that brings a very interesting question for me, though. Where exactly is the safepoint for the STW when `Future::get` is invoked with a timeout? I don't know that. Or simpler may be : is the timeout "paused" during a STW event? – Eugene Jan 09 '20 at 20:00

0 Answers0