Reputation: 4073
I'm a newbie in Finagle. I'm now reading someone's code and found that a Future object is reused in different join operations. My question is will that cause the Future object to be executed multiple times (in each join), or will it only execute once and store the result for later joins?
Example:
Future<A> a= b
.join(c)
.flatMap(new SomeFunctionReturningA());
Future<Tuple2<A, B>> future1 = a.join(b);
Future<D> future2 = future1.flatMap(new SomeFunctionReturningD());
future2.get();
So will b be executed twice, or just once?
Upvotes: 4
Views: 2426
Reputation: 1227
Future object gets executed only once.
Finagle uses com.twitter.util.A Future is a handle for a value not yet available.
The two most basic ways to use a Future are to: block and wait for the computation to return register a callback to be invoked when the computation eventually succeeds or fails A FuturePool object enables you to place a blocking operation on its own thread.
You can get more understanding of Finagle Future (Future Pool) from twitter blog and fingale github
Upvotes: 1
Reputation: 15658
A Future is just a container for a value, and the value will only be set one time!
The Future[T]
have different states:
When you use map/flatMap
with a function f
on a Future A
, you will just create a new Future B
that will be the result of the previous one transformed by the function f
.
Note that:
A
is not yet 'filled' you will have a not yet filled B
a
in A
will also execute f(a)
and set the value in B
A
is already 'filled' then the caller of map/flatMap will also execute f(a)
, but it will NOT recompute the value of A
.onSuccess/onFailure
that will just register some code to be executed when the future gets its value.Upvotes: 5
Reputation: 4073
I wrote a quick test myself:
import com.twitter.util.Function;
import com.twitter.util.Future;
import java.util.Random;
import org.junit.Test;
import scala.Tuple2;
public class FinagleFutureTest {
int counter = 0;
@Test
public void test(){
Counter counter = new Counter();
Future<Counter> one = Future.value(counter).flatMap(new IncrementFunction());
Future<Counter> two = one.flatMap(new IncrementFunction());
Future<Tuple2<Counter, Counter>> three = two.join(one);
Tuple2<Counter, Counter> tuple = three.flatMap(new TupleFunction()).get();
System.out.println("one: "+ tuple._2().count+", "+tuple._2().randomInt);
System.out.println("two: "+ tuple._1().count+", "+tuple._1().randomInt);
}
static class TupleFunction extends Function<Tuple2<Counter, Counter>, Future<Tuple2<Counter, Counter>>>{
@Override
public Future<Tuple2<Counter, Counter>> apply(Tuple2<Counter, Counter> t1) {
return Future.value(t1);
}
}
static class IncrementFunction extends Function<Counter, Future<Counter>>{
@Override
public Future<Counter> apply(Counter counter) {
counter.add();
return Future.value(counter);
}
}
static class Counter{
public int count = 0;
public int randomInt;
Counter(){
Random random = new Random();
randomInt = random.nextInt();
}
public void add(){
count++;
}
}
}
and here's the result:
one: 2, 2009034289
two: 2, 2009034289
So the conclusion is that Future object is only executed once no matter how many join operations it is involved in.
Upvotes: 1