ListenableFuture链可以处理内部ExecutionException吗? [英] Can a ListenableFuture chain handle inner ExecutionException?

查看:73
本文介绍了ListenableFuture链可以处理内部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:

  1. 对gRPC结果进行一些转换处理,并且其自身返回一个ListenableFuture,解析为转换后的值 t1 .

  1. 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?

推荐答案

我不是番石榴专家,但看来您可以使用相同的

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆