Fix broadcast context being cleared (#10619)
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastClusterInvoker.java
index 2367476..6d03e36 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastClusterInvoker.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastClusterInvoker.java
@@ -28,10 +28,10 @@
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
-import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
-
/**
* BroadcastClusterInvoker
*/
@@ -67,10 +67,15 @@
int failThresholdIndex = invokers.size() * broadcastFailPercent / MAX_BROADCAST_FAIL_PERCENT;
int failIndex = 0;
- for (Invoker<T> invoker : invokers) {
+ for (int i = 0, invokersSize = invokers.size(); i < invokersSize; i++) {
+ Invoker<T> invoker = invokers.get(i);
+ RpcContext.RestoreContext restoreContext = new RpcContext.RestoreContext();
try {
- RpcInvocation subInvocation = new RpcInvocation(invocation, invoker);
- subInvocation.setAttachment(ASYNC_KEY, "true");
+ RpcInvocation subInvocation = new RpcInvocation(invocation.getTargetServiceUniqueName(),
+ invocation.getServiceModel(), invocation.getMethodName(), invocation.getServiceName(), invocation.getProtocolServiceKey(),
+ invocation.getParameterTypes(), invocation.getArguments(), invocation.copyObjectAttachments(),
+ invocation.getInvoker(), Collections.synchronizedMap(new HashMap<>(invocation.getAttributes())),
+ invocation instanceof RpcInvocation ? ((RpcInvocation) invocation).getInvokeMode() : null);
result = invokeWithContext(invoker, subInvocation);
if (null != result && result.hasException()) {
Throwable resultException = result.getException();
@@ -90,6 +95,10 @@
if (failIndex == failThresholdIndex) {
break;
}
+ } finally {
+ if (i != invokersSize - 1) {
+ restoreContext.restore();
+ }
}
}