DaveAKing / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

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

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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.

Original issue reported on code.google.com by kristofer.karlsson@gmail.com on 22 May 2013 at 3:01

Attachments:

GoogleCodeExporter commented 9 years ago
Though we've stayed away from Function2 and friends 
(<https://code.google.com/p/guava-libraries/wiki/IdeaGraveyard#Functions/Predica
tes_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.

Original comment by cpov...@google.com on 22 May 2013 at 3:09

GoogleCodeExporter commented 9 years ago
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);

Original comment by kristofer.karlsson@gmail.com on 22 May 2013 at 3:19

GoogleCodeExporter commented 9 years ago
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.

Original comment by cpov...@google.com on 22 May 2013 at 3:27

GoogleCodeExporter commented 9 years ago
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. 

Original comment by petterma...@gmail.com on 31 Jan 2014 at 9:24

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<issue id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:12

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:17

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:08