Java 如果原始ApiFuture/ListenableFuture失败或取消,Futures.transform()lambda参数是什么
我有一个异步发送消息列表的方法。每次发送都返回Java 如果原始ApiFuture/ListenableFuture失败或取消,Futures.transform()lambda参数是什么,java,asynchronous,google-cloud-platform,guava,future,Java,Asynchronous,Google Cloud Platform,Guava,Future,我有一个异步发送消息列表的方法。每次发送都返回ApiFuture(Guava的GCP版本ListenableFuture)。我需要此方法返回一个Future,因此 在每个ApiFuture 使用ApiFutures.Transform方法将结果ApiFuture转换为Future apifurtureallsentfurture=apifurtures.allAsList(futures); 返回ApiFutures.transform(allSentFuture,val->{ 返回true;
ApiFuture
(Guava的GCP版本ListenableFuture
)。我需要此方法返回一个Future
,因此
ApiFuture
ApiFutures.Transform
方法将结果ApiFuture
转换为Future
apifurture>allsentfurture=apifurtures.allAsList(futures);
返回ApiFutures.transform(allSentFuture,val->{
返回true;
},
Executors.newCachedThreadPool()
);
我的问题是:如果一个或多个原始期货失败/取消,上面lambda的val
参数的值是多少?在这种情况下,lambda被调用了吗
谢谢 apifourt
在类型V
上形成一个单子,并且transform
将函数应用于类型V
的封装值。如果apifourture
由于失败或取消而不包含V
值,则转换后的未来是相同的
如果要处理异常导致的故障,可以使用apifourtures.catching()
生成替代结果(例如Boolean.FALSE
)
如果您想将取消转换为成功的值,我相信您需要直接使用ApiFuture.addListener
,并让侦听器完成一个SettableApiFuture
,然后返回。然后监听器(在源未来被取消时将被调用)可以检查isCancelled
来检测这种情况,或者可以捕获并处理取消异常
例如:
/**
* Adapt an iterable of {@link ApiFuture} instances into a single {@code ApiFuture}.
*/
static <T> ApiFuture<Boolean> adaptFutures(Iterable<ApiFuture<T>> futures) {
final SettableApiFuture<Boolean> result = SettableApiFuture.create();
final ApiFuture<List<T>> allFutures = ApiFutures.allAsList(futures);
allFutures.addListener(
() -> {
if (allFutures.isCancelled()) {
result.set(Boolean.FALSE);
return;
}
try {
allFutures.get();
result.set(Boolean.TRUE);
} catch (ExecutionException | InterruptedException ex) {
// Maybe log something here?
//
// Note that InterruptedException is actually impossible here
// because we're running in the listener callback, but the API
// still marks it as potentially thrown by .get() above.
//
// So if we reach here it means that the allAsList future failed.
result.set(Boolean.FALSE);
}
},
// Not normally safe, but we know our listener runs fast enough
// to run inline on the thread that completes the last future.
Runnable::run);
return result;
}
/**
*将{@link APIFURTURE}实例的iterable适配为单个{@code APIFURTURE}。
*/
静态期货(可转换期货){
最终SettableApiFuture结果=SettableApiFuture.create();
最终ApiFuture allFutures=ApiFutures.allAsList(futures);
allFutures.addListener(
() -> {
if(allFutures.isCancelled()){
result.set(Boolean.FALSE);
返回;
}
试一试{
all futures.get();
result.set(Boolean.TRUE);
}捕获(ExecutionException | InterruptedException ex){
//也许在这里写点什么?
//
//请注意,中断异常在这里实际上是不可能的
//因为我们在侦听器回调中运行,但是API
//仍然将其标记为可能由上面的.get()引发。
//
//因此,如果我们到达这里,这意味着所有人的未来都失败了。
result.set(Boolean.FALSE);
}
},
//通常不安全,但我们知道我们的听众跑得足够快
//在最后一个将来完成的线程上内联运行。
Runnable::run);
返回结果;
}
它没有被调用。@CliveEvans如果调用方在最终结果上调用wait(),会发生什么?是否引发异常?
/**
* Adapt an iterable of {@link ApiFuture} instances into a single {@code ApiFuture}.
*/
static <T> ApiFuture<Boolean> adaptFutures(Iterable<ApiFuture<T>> futures) {
final SettableApiFuture<Boolean> result = SettableApiFuture.create();
final ApiFuture<List<T>> allFutures = ApiFutures.allAsList(futures);
allFutures.addListener(
() -> {
if (allFutures.isCancelled()) {
result.set(Boolean.FALSE);
return;
}
try {
allFutures.get();
result.set(Boolean.TRUE);
} catch (ExecutionException | InterruptedException ex) {
// Maybe log something here?
//
// Note that InterruptedException is actually impossible here
// because we're running in the listener callback, but the API
// still marks it as potentially thrown by .get() above.
//
// So if we reach here it means that the allAsList future failed.
result.set(Boolean.FALSE);
}
},
// Not normally safe, but we know our listener runs fast enough
// to run inline on the thread that completes the last future.
Runnable::run);
return result;
}