diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java index eaf8f69353..a1334aab07 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java @@ -30,6 +30,8 @@ import org.apache.dubbo.rpc.cluster.LoadBalance; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -84,27 +86,28 @@ public class ForkingClusterInvoker extends AbstractClusterInvoker { RpcContext.getServiceContext().setInvokers((List) selected); final AtomicInteger count = new AtomicInteger(); final BlockingQueue ref = new LinkedBlockingQueue<>(1); - for (final Invoker invoker : selected) { + selected.forEach(invoker -> { URL consumerUrl = RpcContext.getServiceContext().getConsumerUrl(); - executor.execute(() -> { - try { - if (ref.size() > 0) { - return; - } - Result result = invokeWithContextAsync(invoker, invocation, consumerUrl); - ref.offer(result); - } catch (Throwable e) { + CompletableFuture.supplyAsync(() -> { + if (ref.size() > 0) { + return null; + } + return invokeWithContextAsync(invoker, invocation, consumerUrl); + }, executor).whenComplete((v, t) -> { + if (t == null) { + ref.offer(v); + } else { int value = count.incrementAndGet(); if (value >= selected.size()) { - ref.offer(e); + ref.offer(t); } } }); - } + }); try { Object ret = ref.poll(timeout, TimeUnit.MILLISECONDS); if (ret instanceof Throwable) { - Throwable e = (Throwable) ret; + Throwable e = ret instanceof CompletionException ? ((CompletionException) ret).getCause() : (Throwable) ret; throw new RpcException(e instanceof RpcException ? ((RpcException) e).getCode() : RpcException.UNKNOWN_EXCEPTION, "Failed to forking invoke provider " + selected + ", but no luck to perform the invocation. " + "Last error is: " + e.getMessage(), e.getCause() != null ? e.getCause() : e);