Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to chain async calls using Guava?

Tags:

java

guava

I want to chain async rest service calls and have single callback when they finished.

Is it possible to do it with guava?

like image 436
Alexey Zakharov Avatar asked Nov 19 '11 04:11

Alexey Zakharov


People also ask

Why does guava run in the same thread as the while loop?

This is because Guava executes all listeners in a while loop in their respective Executors, but the directExecutor will cause the listener to run in the same thread as the while loop. 5.3. Nesting Futures Is Bad

How do I use listenablefuture in guava?

Guava recommends that the best way we can leverage its ListenableFuture is by converting all our code that uses Future to ListenableFuture. If this conversion is not feasible in some scenarios, Guava provides us with adapters to do this using the JdkFutureAdapters.listenInPoolThread () overrides.

What are the problems with async calls in Java?

Another problem with async calls is that they are often very difficult to read. The first problem with blocking async calls is that it turns asynchronous code into synchronous code. This can lead to unexpected blocking of context threads and deadlocks.

What are the different types of fan-in operations in guava?

Similar to the simple fan-in operations, Guava provides us with two variants; one that succeeds when all tasks complete successfully and one that succeeds even if some tasks fail using the Futures.whenAllSucceed () and Futures.whenAllComplete () methods, respectively.


2 Answers

Futures.chain was removed in version 12.0. The new method of chaining together ListenableFutures is via the Futures.transform method.

https://github.com/google/guava/wiki/ListenableFutureExplained#application

From Guava latest javadoc (16.0.1 as of this writing).

ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
AsyncFunction<RowKey, QueryResult> queryFunction =
   new AsyncFunction<RowKey, QueryResult>() {
   public ListenableFuture<QueryResult> apply(RowKey rowKey) {
      return dataService.read(rowKey);
   }
};
ListenableFuture<QueryResult> queryFuture = transform(rowKeyFuture, queryFunction);
like image 181
Cooper Avatar answered Oct 17 '22 06:10

Cooper


You can use Futures.chain for chaining ListenableFutures:

final ListeningExecutorService service1 = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(16));
final ListeningExecutorService service2 = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(16));

ListenableFuture<String> service1result = service1.submit(new Callable<String>() {
    @Override
    public String call() throws Exception {
        return "service1result";
    }
});

ListenableFuture<String> service2result = Futures.chain(service1result, new Function<String, ListenableFuture<String>>() {
    @Override
    public ListenableFuture<String> apply(final @Nullable String input) {
        return service2.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return Joiner.on(" -> ").join(input, "service2result");
            }
        });
    }
});

System.out.format("Result: %s\r\n", service2result.get());

Output of at the code above in the terminal:

> run-main training.Training
[info] Compiling 1 Java source to /home/remeniuk/projects/guava-training/target/scala-2.9.1/classes...
[info] Running training.Training 
Result: service1result -> service2result
like image 37
Vasil Remeniuk Avatar answered Oct 17 '22 07:10

Vasil Remeniuk