guava icon indicating copy to clipboard operation
guava copied to clipboard

Feature request: add support for transforming a tuple of futures into a single future

Open gissuebot opened this issue 11 years ago • 7 comments
trafficstars

Original issue created by kristofer.karlsson on 2013-05-22 at 03:01 PM


Sometimes it would be useful to combine the result of multiple futures into a single result, basically transforming a set of futures into a single future.

This is already supported to some extent through Futures.allAsList, but that only works if all futures are of the same type. I would want something similar, but that works on tuples instead of lists.

Something like this: ListenableFuture<A> future1; ListenableFuture<B> future1; Function2<X, A, B> function = new Function2<X, A, B>(){   @Override   public X apply(A first, B second) {     return merge(first, second);   } }; ListenableFuture<X> result = Futures.transform(future1, future2, function);

Attached is some sort of minimal implementation of this concept.

gissuebot avatar Oct 31 '14 17:10 gissuebot

Original comment posted by [email protected] on 2013-05-22 at 03:09 PM


Though we've stayed away from Function2 and friends (<https://code.google.com/p/guava-libraries/wiki/IdeaGraveyard#Functions/Predicates_for_n_%3E=_2_inputs>), we can find other ways of merging Futures:

final ListenableFuture<A> future1; final ListenableFuture<B> future2; Callable<X> function = new Callable<X>() {   @Override   public X call() {     return merge(future1.get(), future2.get());   } }; ListenableFuture<X> result = Futures.combine(function, executor, future1, future2);

In fact, we have this method internally. It may yet make its way out.

gissuebot avatar Nov 01 '14 01:11 gissuebot

Original comment posted by kristofer.karlsson on 2013-05-22 at 03:19 PM


Thanks for quick response. But if that's the route you're going for it, I could just wrap things as a list instead and do this:

final ListenableFuture<A> future1; final ListenableFuture<B> future1; Function<X, ?> function = new Function<X, ?>(){   @Override   public X apply(List<?> dummy) {     return merge(future1.get(), future2.get());   } }; ListenableFuture<X> result = Futures.transform(Futures.allAsList(future1, future2), function);

so you wouldn't actually need to expose your combine. The tuple version is cute, since it gives somewhat nicer type information, and you don't need to invoke outer objects.

You could also do this, but I'm not sure it's any prettier: ListenableFuture<A> future1; ListenableFuture<B> future1; Function<X, ?> function = new Function<X, ?>(){   @Override   public X apply(List<?> result) {     return merge((A) result.get(0), (B) result.get(0));   } }; ListenableFuture<X> result = Futures.transform(Futures.allAsList(future1, future2), function);

gissuebot avatar Nov 01 '14 01:11 gissuebot

Original comment posted by [email protected] on 2013-05-22 at 03:27 PM


Yep, allAsList+transform is pretty much how ours is implemented. (As it turns out, ours (a) uses successfulAsList so that you can choose to handle exceptions manually (or just let them propagate) and (b) uses the AsyncFunction version of transform() so that the Function can throw any kind of Exception (important in part because we make you call get() but also sometimes convenient for other reasons.)

Part of what keeps us from going to tuple route is that, if we're going to address complex graphs of Futures, we probably want to go even further than an added method or two. There's at least one popular system available internally at Google, so we're kind of spoiled.

gissuebot avatar Nov 01 '14 01:11 gissuebot

Original comment posted by pettermahlen on 2014-01-31 at 09:24 AM


We've created a framework that aims to simplify the problem of working with non-trivial asynchronous call graphs: https://github.com/spotify/trickle. It may be of interest until the day when the Google-internal system is made available to the public.

gissuebot avatar Nov 01 '14 01:11 gissuebot

Let's call this the bug for de-@Beta-ing the FutureCombiner type.

cpovirk avatar Mar 25 '19 19:03 cpovirk

This is now fixed.

kluever avatar Apr 11 '23 18:04 kluever

While I did say...

Let's call this the bug for de-@Beta-ing the FutureCombiner type.

...I think I had written that under the assumption that we wouldn't be de-@Beta-ing it until we added the functionality described in the initial post here. So let's have this open to track such an enhancement, even though we remain unlikely to do it anytime soon :(

cpovirk avatar Apr 11 '23 18:04 cpovirk