This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 81ac64d7b6 [3.0] Fix some context related issues (#9923)
81ac64d7b6 is described below

commit 81ac64d7b6c7b0b7a91e8b39c59875a50ac3ef23
Author: Albumen Kevin <[email protected]>
AuthorDate: Wed Apr 20 16:44:59 2022 +0800

    [3.0] Fix some context related issues (#9923)
---
 .../filter/support/ConsumerContextFilter.java      |  94 +++++++++--------
 .../common/threadlocal/InternalThreadLocal.java    |  10 ++
 .../main/java/org/apache/dubbo/rpc/RpcContext.java |  35 +++++++
 .../java/org/apache/dubbo/rpc/RpcInvocation.java   | 113 ++++++++++++++++-----
 .../org/apache/dubbo/rpc/RpcServiceContext.java    |  13 ++-
 .../org/apache/dubbo/rpc/filter/GenericFilter.java |   9 +-
 .../dubbo/rpc/proxy/InvokerInvocationHandler.java  |   2 +-
 .../dubbo/rpc/protocol/injvm/InjvmInvoker.java     |  22 ++--
 8 files changed, 217 insertions(+), 81 deletions(-)

diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ConsumerContextFilter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ConsumerContextFilter.java
index e7c71b3d99..e793727d92 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ConsumerContextFilter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ConsumerContextFilter.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.InvokeMode;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.PenetrateAttachmentSelector;
 import org.apache.dubbo.rpc.Result;
@@ -50,63 +51,66 @@ import static 
org.apache.dubbo.common.constants.CommonConstants.TIME_COUNTDOWN_K
 @Activate(group = CONSUMER, order = Integer.MIN_VALUE)
 public class ConsumerContextFilter implements ClusterFilter, 
ClusterFilter.Listener {
 
-    private ApplicationModel applicationModel;
     private Set<PenetrateAttachmentSelector> supportedSelectors;
 
     public ConsumerContextFilter(ApplicationModel applicationModel) {
-        this.applicationModel = applicationModel;
         ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader = 
applicationModel.getExtensionLoader(PenetrateAttachmentSelector.class);
         supportedSelectors = 
selectorExtensionLoader.getSupportedExtensionInstances();
     }
 
     @Override
     public Result invoke(Invoker<?> invoker, Invocation invocation) throws 
RpcException {
-        RpcContext.getServiceContext()
+        RpcContext.RestoreServiceContext originServiceContext = 
RpcContext.storeServiceContext();
+        try {
+            RpcContext.getServiceContext()
                 .setInvoker(invoker)
                 .setInvocation(invocation)
                 .setLocalAddress(NetUtils.getLocalHost(), 0);
 
-        RpcContext context = RpcContext.getClientAttachment();
-        context.setAttachment(REMOTE_APPLICATION_KEY, 
invoker.getUrl().getApplication());
-        if (invocation instanceof RpcInvocation) {
-            ((RpcInvocation) invocation).setInvoker(invoker);
-        }
+            RpcContext context = RpcContext.getClientAttachment();
+            context.setAttachment(REMOTE_APPLICATION_KEY, 
invoker.getUrl().getApplication());
+            if (invocation instanceof RpcInvocation) {
+                ((RpcInvocation) invocation).setInvoker(invoker);
+            }
 
-        if (CollectionUtils.isNotEmpty(supportedSelectors)) {
-            for (PenetrateAttachmentSelector supportedSelector : 
supportedSelectors) {
-                Map<String, Object> selected = supportedSelector.select();
-                if (CollectionUtils.isNotEmptyMap(selected)) {
-                    ((RpcInvocation) 
invocation).addObjectAttachments(selected);
+            if (CollectionUtils.isNotEmpty(supportedSelectors)) {
+                for (PenetrateAttachmentSelector supportedSelector : 
supportedSelectors) {
+                    Map<String, Object> selected = supportedSelector.select();
+                    if (CollectionUtils.isNotEmptyMap(selected)) {
+                        ((RpcInvocation) 
invocation).addObjectAttachments(selected);
+                    }
                 }
+            } else {
+                ((RpcInvocation) 
invocation).addObjectAttachments(RpcContext.getServerAttachment().getObjectAttachments());
             }
-        } else {
-            ((RpcInvocation) 
invocation).addObjectAttachments(RpcContext.getServerAttachment().getObjectAttachments());
-        }
 
-        Map<String, Object> contextAttachments = 
RpcContext.getClientAttachment().getObjectAttachments();
-        if (CollectionUtils.isNotEmptyMap(contextAttachments)) {
-            /**
-             * invocation.addAttachmentsIfAbsent(context){@link 
RpcInvocation#addAttachmentsIfAbsent(Map)}should not be used here,
-             * because the {@link RpcContext#setAttachment(String, String)} is 
passed in the Filter when the call is triggered
-             * by the built-in retry mechanism of the Dubbo. The attachment to 
update RpcContext will no longer work, which is
-             * a mistake in most cases (for example, through Filter to 
RpcContext output traceId and spanId and other information).
-             */
-            ((RpcInvocation) 
invocation).addObjectAttachments(contextAttachments);
-        }
+            Map<String, Object> contextAttachments = 
RpcContext.getClientAttachment().getObjectAttachments();
+            if (CollectionUtils.isNotEmptyMap(contextAttachments)) {
+                /**
+                 * invocation.addAttachmentsIfAbsent(context){@link 
RpcInvocation#addAttachmentsIfAbsent(Map)}should not be used here,
+                 * because the {@link RpcContext#setAttachment(String, 
String)} is passed in the Filter when the call is triggered
+                 * by the built-in retry mechanism of the Dubbo. The 
attachment to update RpcContext will no longer work, which is
+                 * a mistake in most cases (for example, through Filter to 
RpcContext output traceId and spanId and other information).
+                 */
+                ((RpcInvocation) 
invocation).addObjectAttachments(contextAttachments);
+            }
 
-        // pass default timeout set by end user (ReferenceConfig)
-        Object countDown = context.getObjectAttachment(TIME_COUNTDOWN_KEY);
-        if (countDown != null) {
-            TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countDown;
-            if (timeoutCountDown.isExpired()) {
-                return AsyncRpcResult.newDefaultAsyncResult(new 
RpcException(RpcException.TIMEOUT_TERMINATE,
-                    "No time left for making the following call: " + 
invocation.getServiceName() + "."
-                        + invocation.getMethodName() + ", terminate 
directly."), invocation);
+            // pass default timeout set by end user (ReferenceConfig)
+            Object countDown = context.getObjectAttachment(TIME_COUNTDOWN_KEY);
+            if (countDown != null) {
+                TimeoutCountDown timeoutCountDown = (TimeoutCountDown) 
countDown;
+                if (timeoutCountDown.isExpired()) {
+                    return AsyncRpcResult.newDefaultAsyncResult(new 
RpcException(RpcException.TIMEOUT_TERMINATE,
+                        "No time left for making the following call: " + 
invocation.getServiceName() + "."
+                            + invocation.getMethodName() + ", terminate 
directly."), invocation);
+                }
             }
-        }
 
-        RpcContext.removeServerContext();
-        return invoker.invoke(invocation);
+            RpcContext.removeServerContext();
+            return invoker.invoke(invocation);
+        } finally {
+            RpcContext.restoreServiceContext(originServiceContext);
+        }
     }
 
     @Override
@@ -114,17 +118,25 @@ public class ConsumerContextFilter implements 
ClusterFilter, ClusterFilter.Liste
         // pass attachments to result
         
RpcContext.getServerContext().setObjectAttachments(appResponse.getObjectAttachments());
 
-        removeContext();
+        removeContext(invocation);
     }
 
     @Override
     public void onError(Throwable t, Invoker<?> invoker, Invocation 
invocation) {
-        removeContext();
+        removeContext(invocation);
     }
 
-    private void removeContext() {
-        RpcContext.removeServiceContext();
+    private void removeContext(Invocation invocation) {
         RpcContext.removeClientAttachment();
+        if (invocation instanceof RpcInvocation) {
+            RpcInvocation rpcInvocation = (RpcInvocation) invocation;
+            if (rpcInvocation.getInvokeMode() != null) {
+                // clear service context if not in sync mode
+                if (rpcInvocation.getInvokeMode() == InvokeMode.ASYNC || 
rpcInvocation.getInvokeMode() == InvokeMode.FUTURE) {
+                    RpcContext.removeServiceContext();
+                }
+            }
+        }
         // server context must not be removed because user might use it on 
callback.
         // So the clear of is delayed til the start of the next rpc call, see 
RpcContext.removeServerContext(); in invoke() above
         // RpcContext.removeServerContext();
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java
index d0783c84de..e3108c89d5 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/threadlocal/InternalThreadLocal.java
@@ -126,6 +126,16 @@ public class InternalThreadLocal<V> extends ThreadLocal<V> 
{
         return initialize(threadLocalMap);
     }
 
+    public final V getWithoutInitialize() {
+        InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get();
+        Object v = threadLocalMap.indexedVariable(index);
+        if (v != InternalThreadLocalMap.UNSET) {
+            return (V) v;
+        }
+
+        return null;
+    }
+
     private V initialize(InternalThreadLocalMap threadLocalMap) {
         V v = null;
         try {
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java
index 67b24a3e21..cfe7f9a821 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java
@@ -176,6 +176,10 @@ public class RpcContext {
         return SERVICE_CONTEXT.get();
     }
 
+    public static RpcServiceContext getCurrentServiceContext() {
+        return SERVICE_CONTEXT.getWithoutInitialize();
+    }
+
     public static void removeServiceContext() {
         SERVICE_CONTEXT.remove();
     }
@@ -801,6 +805,16 @@ public class RpcContext {
         return new RestoreContext();
     }
 
+    public static RestoreServiceContext storeServiceContext() {
+        return new RestoreServiceContext();
+    }
+
+    public static void restoreServiceContext(RestoreServiceContext 
restoreServiceContext) {
+        if (restoreServiceContext != null) {
+            restoreServiceContext.restore();
+        }
+    }
+
     protected static void restoreContext(RestoreContext restoreContext) {
         if (restoreContext != null) {
             restoreContext.restore();
@@ -846,4 +860,25 @@ public class RpcContext {
             }
         }
     }
+
+    public static class RestoreServiceContext {
+        private final RpcServiceContext serviceContext;
+
+        public RestoreServiceContext() {
+            RpcServiceContext originContext = getCurrentServiceContext();
+            if (originContext == null) {
+                this.serviceContext = null;
+            } else {
+                this.serviceContext = originContext.copyOf(true);
+            }
+        }
+
+        protected void restore() {
+            if (serviceContext != null) {
+                SERVICE_CONTEXT.set(serviceContext);
+            } else {
+                removeServiceContext();
+            }
+        }
+    }
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
index 6a13ef2d70..db9a7e7cb3 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
@@ -87,13 +87,33 @@ public class RpcInvocation implements Invocation, 
Serializable {
 
     private transient InvokeMode invokeMode;
 
+    /**
+     * @deprecated only for test
+     */
+    @Deprecated
     public RpcInvocation() {
     }
 
+    /**
+     * Deep clone of an invocation
+     *
+     * @param invocation original invocation
+     */
+    public RpcInvocation(Invocation invocation) {
+        this(invocation, null);
+    }
+
+    /**
+     * Deep clone of an invocation & put some service params into attachment 
from invoker (will not change the invoker in invocation)
+     *
+     * @param invocation original invocation
+     * @param invoker target invoker
+     */
     public RpcInvocation(Invocation invocation, Invoker<?> invoker) {
-        this(invocation.getServiceModel(), invocation.getMethodName(), 
invocation.getServiceName(), invocation.getProtocolServiceKey(),
-                invocation.getParameterTypes(), invocation.getArguments(), new 
HashMap<>(invocation.getObjectAttachments()),
-                invocation.getInvoker(), invocation.getAttributes());
+        this(invocation.getTargetServiceUniqueName(), 
invocation.getServiceModel(), invocation.getMethodName(), 
invocation.getServiceName(),
+            invocation.getProtocolServiceKey(), 
invocation.getParameterTypes(), invocation.getArguments(),
+            new HashMap<>(invocation.getObjectAttachments()), 
invocation.getInvoker(), invocation.getAttributes(),
+            invocation instanceof RpcInvocation ? ((RpcInvocation) 
invocation).getInvokeMode() : null);
         if (invoker != null) {
             URL url = invoker.getUrl();
             setAttachment(PATH_KEY, url.getPath());
@@ -116,65 +136,103 @@ public class RpcInvocation implements Invocation, 
Serializable {
                 setAttachment(APPLICATION_KEY, url.getApplication());
             }
         }
-        this.targetServiceUniqueName = invocation.getTargetServiceUniqueName();
-        this.protocolServiceKey = invocation.getProtocolServiceKey();
     }
 
-    public RpcInvocation(Invocation invocation) {
-        this(invocation.getServiceModel(), invocation.getMethodName(), 
invocation.getServiceName(), invocation.getProtocolServiceKey(), 
invocation.getParameterTypes(),
-                invocation.getArguments(), invocation.getObjectAttachments(), 
invocation.getInvoker(), invocation.getAttributes());
-        this.targetServiceUniqueName = invocation.getTargetServiceUniqueName();
+    /**
+     * To create a brand-new invocation
+     */
+    public RpcInvocation(ServiceModel serviceModel, String methodName, String 
interfaceName, String protocolServiceKey, Class<?>[] parameterTypes, Object[] 
arguments) {
+        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, null, null, null, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
+    @Deprecated
     public RpcInvocation(ServiceModel serviceModel, Method method, String 
interfaceName, String protocolServiceKey, Object[] arguments) {
-        this(serviceModel, method, interfaceName, protocolServiceKey, 
arguments, null, null);
+        this(null, serviceModel, method.getName(), interfaceName, 
protocolServiceKey, method.getParameterTypes(), arguments, null, null, null, 
null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
     @Deprecated
     public RpcInvocation(Method method, String interfaceName, String 
protocolServiceKey, Object[] arguments) {
-        this(null, method, interfaceName, protocolServiceKey, arguments, null, 
null);
+        this(null, null, method.getName(), interfaceName, protocolServiceKey, 
method.getParameterTypes(), arguments, null, null, null, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
+    @Deprecated
     public RpcInvocation(ServiceModel serviceModel, Method method, String 
interfaceName, String protocolServiceKey, Object[] arguments, Map<String, 
Object> attachment, Map<Object, Object> attributes) {
-        this(null, serviceModel, method.getName(), interfaceName, 
protocolServiceKey, method.getParameterTypes(), arguments, attachment, null, 
attributes);
+        this(null, serviceModel, method.getName(), interfaceName, 
protocolServiceKey, method.getParameterTypes(), arguments, attachment, null, 
attributes, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
     @Deprecated
     public RpcInvocation(Method method, String interfaceName, String 
protocolServiceKey, Object[] arguments, Map<String, Object> attachment, 
Map<Object, Object> attributes) {
-        this(null, null, method.getName(), interfaceName, protocolServiceKey, 
method.getParameterTypes(), arguments, attachment, null, attributes);
-    }
-
-    public RpcInvocation(ServiceModel serviceModel, String methodName, String 
interfaceName, String protocolServiceKey, Class<?>[] parameterTypes, Object[] 
arguments) {
-        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, null, null, null);
+        this(null, null, method.getName(), interfaceName, protocolServiceKey, 
method.getParameterTypes(), arguments, attachment, null, attributes, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
     @Deprecated
     public RpcInvocation(String methodName, String interfaceName, String 
protocolServiceKey, Class<?>[] parameterTypes, Object[] arguments) {
-        this(null, null, methodName, interfaceName, protocolServiceKey, 
parameterTypes, arguments, null, null, null);
+        this(null, null, methodName, interfaceName, protocolServiceKey, 
parameterTypes, arguments, null, null, null, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
+    @Deprecated
     public RpcInvocation(ServiceModel serviceModel, String methodName, String 
interfaceName, String protocolServiceKey, Class<?>[] parameterTypes, Object[] 
arguments, Map<String, Object> attachments) {
-        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, attachments, null, null);
+        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, attachments, null, null, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
     @Deprecated
     public RpcInvocation(String methodName, String interfaceName, String 
protocolServiceKey, Class<?>[] parameterTypes, Object[] arguments, Map<String, 
Object> attachments) {
-        this(null, null, methodName, interfaceName, protocolServiceKey, 
parameterTypes, arguments, attachments, null, null);
+        this(null, null, methodName, interfaceName, protocolServiceKey, 
parameterTypes, arguments, attachments, null, null, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
     @Deprecated
     public RpcInvocation(String methodName, String interfaceName, String 
protocolServiceKey, Class<?>[] parameterTypes, Object[] arguments,
                          Map<String, Object> attachments, Invoker<?> invoker, 
Map<Object, Object> attributes) {
-        this(null, null, methodName, interfaceName, protocolServiceKey, 
parameterTypes, arguments, attachments, invoker, attributes);
+        this(null, null, methodName, interfaceName, protocolServiceKey, 
parameterTypes, arguments, attachments, invoker, attributes, null);
     }
 
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
+    @Deprecated
     public RpcInvocation(ServiceModel serviceModel, String methodName, String 
interfaceName, String protocolServiceKey, Class<?>[] parameterTypes, Object[] 
arguments,
                          Map<String, Object> attachments, Invoker<?> invoker, 
Map<Object, Object> attributes) {
-        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, attachments, invoker, 
attributes);
+        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, attachments, invoker, 
attributes, null);
+    }
+
+    /**
+     * @deprecated deprecated, will be removed in 3.1.x
+     */
+    @Deprecated
+    public RpcInvocation(ServiceModel serviceModel, String methodName, String 
interfaceName, String protocolServiceKey, Class<?>[] parameterTypes, Object[] 
arguments,
+                         Map<String, Object> attachments, Invoker<?> invoker, 
Map<Object, Object> attributes, InvokeMode invokeMode) {
+        this(null, serviceModel, methodName, interfaceName, 
protocolServiceKey, parameterTypes, arguments, attachments, invoker, 
attributes, invokeMode);
     }
 
+    /**
+     * To create a brand-new invocation
+     */
     public RpcInvocation(String targetServiceUniqueName, ServiceModel 
serviceModel, String methodName, String interfaceName, String 
protocolServiceKey, Class<?>[] parameterTypes, Object[] arguments,
-                         Map<String, Object> attachments, Invoker<?> invoker, 
Map<Object, Object> attributes) {
+                         Map<String, Object> attachments, Invoker<?> invoker, 
Map<Object, Object> attributes, InvokeMode invokeMode) {
         this.targetServiceUniqueName = targetServiceUniqueName;
         this.serviceModel = serviceModel;
         this.methodName = methodName;
@@ -186,20 +244,21 @@ public class RpcInvocation implements Invocation, 
Serializable {
         this.attributes = attributes == null ? Collections.synchronizedMap(new 
HashMap<>()) : attributes;
         this.invoker = invoker;
         initParameterDesc();
+        this.invokeMode = invokeMode;
     }
 
     private void initParameterDesc() {
         AtomicReference<ServiceDescriptor> serviceDescriptor = new 
AtomicReference<>();
         if (serviceModel != null) {
             serviceDescriptor.set(serviceModel.getServiceModel());
-        } else if (StringUtils.isNotEmpty(interfaceName)){
+        } else if (StringUtils.isNotEmpty(interfaceName)) {
             // TODO: Multi Instance compatible mode
             FrameworkModel.defaultModel()
                 .getServiceRepository()
                 .allProviderModels()
                 .stream()
                 .map(ProviderModel::getServiceModel)
-                .filter(s-> interfaceName.equals(s.getInterfaceName()))
+                .filter(s -> interfaceName.equals(s.getInterfaceName()))
                 .findFirst()
                 .ifPresent(serviceDescriptor::set);
         }
@@ -515,8 +574,8 @@ public class RpcInvocation implements Invocation, 
Serializable {
     @Override
     public String toString() {
         return "RpcInvocation [methodName=" + methodName + ", parameterTypes="
-                + Arrays.toString(parameterTypes) + ", arguments=" + 
Arrays.toString(arguments)
-                + ", attachments=" + attachments + "]";
+            + Arrays.toString(parameterTypes) + ", arguments=" + 
Arrays.toString(arguments)
+            + ", attachments=" + attachments + "]";
     }
 
 }
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java
index 8662493434..f92882ec3e 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcServiceContext.java
@@ -625,10 +625,21 @@ public class RpcServiceContext extends RpcContext {
     public RpcServiceContext copyOf(boolean needCopy) {
         if (needCopy) {
             RpcServiceContext copy = new RpcServiceContext();
+            copy.arguments = this.arguments;
             copy.consumerUrl = this.consumerUrl;
+            copy.invocation = this.invocation;
+            copy.invokers = this.invokers;
+            copy.invoker = this.invoker;
             copy.localAddress = this.localAddress;
+            copy.methodName = this.methodName;
+            copy.needPrintRouterSnapshot = this.needPrintRouterSnapshot;
+            copy.parameterTypes = this.parameterTypes;
             copy.remoteAddress = this.remoteAddress;
-            copy.invocation = this.invocation;
+            copy.remoteApplicationName = this.remoteApplicationName;
+            copy.request = this.request;
+            copy.response = this.response;
+            copy.url = this.url;
+            copy.urls = this.urls;
             return copy;
         } else {
             return this;
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
index 0561c17722..96a9d2473a 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
@@ -184,11 +184,10 @@ public class GenericFilter implements Filter, 
Filter.Listener, ScopeModelAware {
                     }
                 }
 
-                RpcInvocation rpcInvocation =
-                        new RpcInvocation(invoker.getUrl().getServiceModel(), 
method, invoker.getInterface().getName(), 
invoker.getUrl().getProtocolServiceKey(), args,
-                                inv.getObjectAttachments(), 
inv.getAttributes());
-                rpcInvocation.setInvoker(inv.getInvoker());
-                
rpcInvocation.setTargetServiceUniqueName(inv.getTargetServiceUniqueName());
+                RpcInvocation rpcInvocation = new 
RpcInvocation(inv.getTargetServiceUniqueName(),
+                    invoker.getUrl().getServiceModel(), method.getName(), 
invoker.getInterface().getName(), invoker.getUrl().getProtocolServiceKey(),
+                    method.getParameterTypes(), args, 
inv.getObjectAttachments(),
+                    inv.getInvoker(), inv.getAttributes(), inv instanceof 
RpcInvocation ? ((RpcInvocation) inv).getInvokeMode() : null);
 
                 return invoker.invoke(rpcInvocation);
             } catch (NoSuchMethodException | ClassNotFoundException e) {
diff --git 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
index a28314447e..ea75da5f22 100644
--- 
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
+++ 
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
@@ -64,7 +64,7 @@ public class InvokerInvocationHandler implements 
InvocationHandler {
         } else if (parameterTypes.length == 1 && "equals".equals(methodName)) {
             return invoker.equals(args[0]);
         }
-        RpcInvocation rpcInvocation = new RpcInvocation(serviceModel, method, 
invoker.getInterface().getName(), protocolServiceKey, args);
+        RpcInvocation rpcInvocation = new RpcInvocation(serviceModel, 
method.getName(), invoker.getInterface().getName(), protocolServiceKey, 
method.getParameterTypes(), args);
 
         if (serviceModel instanceof ConsumerModel) {
             rpcInvocation.put(Constants.CONSUMER_MODEL, serviceModel);
diff --git 
a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
 
b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
index 313e9e2a43..1b99521c8d 100644
--- 
a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
+++ 
b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
@@ -113,10 +113,14 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
             CompletableFuture<AppResponse> appResponseFuture = 
CompletableFuture.supplyAsync(() -> {
                 Result result = invoker.invoke(copiedInvocation);
                 if (result.hasException()) {
-                    return new AppResponse(result.getException());
+                    AppResponse appResponse = new 
AppResponse(result.getException());
+                    appResponse.setObjectAttachments(new 
HashMap<>(result.getObjectAttachments()));
+                    return appResponse;
                 } else {
                     rebuildValue(invocation, desc, result);
-                    return new AppResponse(result.getValue());
+                    AppResponse appResponse = new 
AppResponse(result.getValue());
+                    appResponse.setObjectAttachments(new 
HashMap<>(result.getObjectAttachments()));
+                    return appResponse;
                 }
             }, executor);
             // save for 2.6.x compatibility, for example, TraceFilter in 
Zipkin uses com.alibaba.xxx.FutureAdapter
@@ -127,10 +131,14 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
         } else {
             Result result = invoker.invoke(copiedInvocation);
             if (result.hasException()) {
-                return result;
+                AsyncRpcResult rpcResult = 
AsyncRpcResult.newDefaultAsyncResult(result.getException(), copiedInvocation);
+                rpcResult.setObjectAttachments(new 
HashMap<>(result.getObjectAttachments()));
+                return rpcResult;
             } else {
                 rebuildValue(invocation, desc, result);
-                return result;
+                AsyncRpcResult rpcResult = 
AsyncRpcResult.newDefaultAsyncResult(result.getValue(), copiedInvocation);
+                rpcResult.setObjectAttachments(new 
HashMap<>(result.getObjectAttachments()));
+                return rpcResult;
             }
         }
     }
@@ -164,7 +172,8 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
             RpcInvocation copiedInvocation = new 
RpcInvocation(invocation.getTargetServiceUniqueName(),
                 providerServiceModel, methodName, invocation.getServiceName(), 
invocation.getProtocolServiceKey(),
                 invocation.getParameterTypes(), invocation.getArguments(), new 
HashMap<>(invocation.getObjectAttachments()),
-                invocation.getInvoker(), new HashMap<>());
+                invocation.getInvoker(), new HashMap<>(),
+                invocation instanceof RpcInvocation ? ((RpcInvocation) 
invocation).getInvokeMode() : null);
             copiedInvocation.setInvoker(invoker);
             return copiedInvocation;
         }
@@ -193,7 +202,8 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
                 RpcInvocation copiedInvocation = new 
RpcInvocation(invocation.getTargetServiceUniqueName(),
                     providerServiceModel, methodName, 
invocation.getServiceName(), invocation.getProtocolServiceKey(),
                     pts, realArgument, new 
HashMap<>(invocation.getObjectAttachments()),
-                    invocation.getInvoker(), new HashMap<>());
+                    invocation.getInvoker(), new HashMap<>(),
+                    invocation instanceof RpcInvocation ? ((RpcInvocation) 
invocation).getInvokeMode() : null);
                 copiedInvocation.setInvoker(invoker);
                 return copiedInvocation;
             } finally {

Reply via email to