ListenableFuture链可以处理内部ExecutionException吗? [英] Can a ListenableFuture chain handle inner ExecutionException?
问题描述
我提供了一个执行gRPC调用并返回ListenableFuture
的api( fnGrpc ),该ListenableFuture
解析为某个值 v (其实现是固定的且无法修改).
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).
我想提供一个辅助功能( fnHelper ):
I want to provide a helper function (fnHelper) that:
-
对gRPC结果进行一些转换处理,并且其自身返回一个
ListenableFuture
,解析为转换后的值 t1 .
does some transformational processing on the gRPC result and itself returns a
ListenableFuture
that resolves to the transformed value t1.
处理gRPC调用失败,并返回其他值 t2 ,而不是让 fnHelper 的调用者看到ExecutionException
.
handles failure of the gRPC call, and returns some other value t2 instead of having fnHelper's caller see an ExecutionException
.
我可以使用Futures.transform()
解决(1):
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;
}
});
}
和呼叫者:
package myApp;
// ...
try {
T t = fnHelper().get();
} catch (ExecutionException | InterruptedException ex) {
// ...
}
如何在仍然让fnHelper返回ListenableFuture
并保持非阻塞状态的同时实现(2)?
How can I achieve (2) whilst still having fnHelper return a ListenableFuture
and remain non-blocking?
我可以让 fnHelper 本身创建一个额外的线程,在其中我可以在 fnGrpc 上调用.get()
,但是还有另一种避免这种额外线程的方法吗?>
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?
推荐答案
我不是番石榴专家,但看来您可以使用相同的 catchingAsync
,您可以在其中传递一个返回a的函数ListenableFuture
和后备值(t2
):
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);
然后您应该可以使用transform
方法将其链接起来,该方法可以进行转换:
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));
}
注意::在上一代码段中,我使用了catching
而不是catchingAsync
来与您的问题中的代码保持一致,并且我没有指定执行者.您可能需要将带有 Async
后缀的方法用于非阻塞处理.
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.
这篇关于ListenableFuture链可以处理内部ExecutionException吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!