Retry in Java futures (part 2)

2019-01-04

This is a follow-up to Retry in Java futures. This post presented a snippet of code demonstrating how to compose futures in Java, specifically java.util.concurrent.CompletableFuture. It demonstrated how to swallow exceptions and compose futures including branching etc.

It turns out that I need to interoperate with Guava futures too, specifically com.google.common.util.concurrent.ListenableFuture. In some ways this post can be considered to be a short translation guide for switching back and forth between CompletableFuture and ListenableFuture.

On first encountering ListenableFuture I was dismayed that, unlike CompletableFuture, this interface does not expose any methods for composing futures. CompletableFuture, for example, provides the following and many more:

On deeper inspection, however, we find that Guava eschews interface methods for static helper methods on the com.google.common.util.concurrent.Futures class. Roughly corresponding to the methods mentioned above we find:

My “add-with-retry” example using CompletableFuture looks like:

These are my observations about this:

Regarding the union type comment above, I can think of at least one more principled approach we might take to handling exceptions that does not lose information. We could, for example, introduce a tagged union type as follows:

With the introduction of the tagged union, ValueOrException (roughly equivalent to Haskell’s Either), we can now distinguish accurately between the exceptional case and the null response case.

Here’s my rough translation of this example into Guava futures:

And here’s the accompanying ListenableFutureHelper helper class:

Here are my thoughts:

In order to address the syntactic issues with ListenableFuture, Guava now has com.google.common.util.concurrent.FluentFuture in recent versions of the library. I haven’t had a chance to play with this yet. If I do, I’ll get back to you!

The latest and greatest version of this code can be found in the GitHub project.

Update: Here’s the FluentFuture version

That’s better!

Update 2: Cancellation

You’ll notice that I sneakily introduced early cancellation into the FluentFuture example. If you want to see how I added support for proper cancellation using all three future APIs, please consult the GitHub project.

Related posts

Retry in Java futures

Tags

Java
Concurrency

All content © 2019 Richard Cook. All rights reserved.