stackoverflower
stackoverflower

Reputation: 4073

Finagle Future objects, are they reusable?

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

Answers (3)

Sree Rama
Sree Rama

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

Steve Gury
Steve Gury

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:

  • Empty
  • Set with a value of type T
  • Set with an Exception

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:

  • If the Future A is not yet 'filled' you will have a not yet filled B
  • The thread that set the value a in A will also execute f(a) and set the value in B
  • If A is already 'filled' then the caller of map/flatMap will also execute f(a), but it will NOT recompute the value of A.
  • You can also use onSuccess/onFailure that will just register some code to be executed when the future gets its value.

Upvotes: 5

stackoverflower
stackoverflower

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

Related Questions