问题
I am provided with an api (fnGrpc) that performs a gRPC call and returns a ListenableFuture that resolves to some value v (the implementation of which is fixed and unmodifiable).
I want to provide a helper function (fnHelper) that:
does some transformational processing on the gRPC result and itself returns a
ListenableFuturethat resolves to the transformed value t1.handles failure of the gRPC call, and returns some other value t2 instead of having fnHelper's caller see an
ExecutionException.
I can solve (1) by using Futures.transform():
package myHelper;
ListenableFuture<T> fnHelper() {
return Futures.transform(fnGrpc(), new Function<V, T>() {
@Override
public T apply(V v) {
T t1 = f(v);
return t1;
}
});
}
and the caller:
package myApp;
// ...
try {
T t = fnHelper().get();
} catch (ExecutionException | InterruptedException ex) {
// ...
}
How can I achieve (2) whilst still having fnHelper return a ListenableFuture and remain non-blocking?
I could have fnHelper itself create an additional thread within which I would call .get() on fnGrpc, but is there another way that avoids this additional thread?
回答1:
I'm not an expert in Guava, but it seems you can do that using the same Futures utility class, in particular the method catchingAsync, where you can pass a function that returns a ListenableFuture with the fallback value (t2):
ListenableFuture<Integer> faultTolerantFuture = Futures.catchingAsync(originalFuture,
Exception.class, x -> immediateFuture(t2), executor);
You should then be able to chain this with the transform method, which does the transformation:
ListenableFuture<T> fnHelper() {
return Futures.catching(Futures.transform(fnGrpc(), new Function<V, T>() {
@Override
public T apply(V v) {
T t1 = f(v);
return t1;
}
}),
Exception.class, x -> immediateFuture(t2));
}
Note: In the last snippet, I used catching instead of catchingAsync to be consistent with the code in your question, and I didn't specify an executor. You probably need to use the methods with the Async suffix for non-blocking processing.
来源:https://stackoverflow.com/questions/49036786/can-a-listenablefuture-chain-handle-inner-executionexception