I want to chain async rest service calls and have single callback when they finished.
Is it possible to do it with guava?
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
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.
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.
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.
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);
You can use Futures.chain
for chaining ListenableFuture
s:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With