You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/11/25 06:20:28 UTC
[dubbo] 42/45: fix concurrent modification, copy on context switch
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch release/3.0.14-rpccontext-bugfix
in repository https://gitbox.apache.org/repos/asf/dubbo.git
commit d91e414f2232ada40b17566810e4719a623c39a0
Author: ken.lj <ke...@gmail.com>
AuthorDate: Mon Nov 22 22:27:10 2021 +0800
fix concurrent modification, copy on context switch
---
.../main/java/org/apache/dubbo/rpc/RpcContext.java | 34 +++++++++++++++++++---
.../org/apache/dubbo/rpc/filter/ContextFilter.java | 24 +++++++++++++--
2 files changed, 52 insertions(+), 6 deletions(-)
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 66ac06f..eab2a54 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
@@ -71,8 +71,8 @@ public class RpcContext {
}
};
- protected final Map<String, Object> attachments = new HashMap<>();
- private final Map<String, Object> values = new HashMap<String, Object>();
+ protected Map<String, Object> attachments = new HashMap<>();
+ private Map<String, Object> values = new HashMap<String, Object>();
private List<URL> urls;
@@ -109,6 +109,32 @@ public class RpcContext {
protected RpcContext() {
}
+ protected RpcContext(RpcContext context) {
+ if (context.attachments != null) {
+ this.attachments = new HashMap(context.attachments);
+ }
+ if (context.values != null) {
+ this.values = new HashMap(context.values);
+ }
+ if (context.urls != null) {
+ this.urls = new ArrayList<>(context.urls);
+ }
+ this.url = context.url;
+ this.methodName = context.methodName;
+ this.parameterTypes = context.parameterTypes;
+ this.arguments = context.arguments;
+ this.localAddress = context.localAddress;
+ this.remoteAddress = context.remoteAddress;
+ this.remoteApplicationName = context.remoteApplicationName;
+ this.invokers = context.invokers;
+ this.invoker = context.invoker;
+ this.invocation = context.invocation;
+ this.request = context.request;
+ this.response = context.response;
+ this.asyncContext = context.asyncContext;
+ this.remove = context.remove;
+ }
+
/**
* get server side context.
*
@@ -119,7 +145,7 @@ public class RpcContext {
}
public static void restoreServerContext(RpcContext oldServerContext) {
- SERVER_LOCAL.set(oldServerContext);
+ SERVER_LOCAL.set(new RpcContext(oldServerContext));
}
/**
@@ -149,7 +175,7 @@ public class RpcContext {
}
public static void restoreContext(RpcContext oldContext) {
- LOCAL.set(oldContext);
+ LOCAL.set(new RpcContext(oldContext));
}
/**
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
index 291601a..d165558 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
@@ -17,6 +17,8 @@
package org.apache.dubbo.rpc.filter;
import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
@@ -28,11 +30,17 @@ import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.TimeoutCountDown;
import org.apache.dubbo.rpc.support.RpcUtils;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.Arrays;
+import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -57,7 +65,7 @@ import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
*/
@Activate(group = PROVIDER, order = -10000)
public class ContextFilter implements Filter, Filter.Listener {
-
+ private static final Logger logger = LoggerFactory.getLogger(ContextFilter.class);
private static final String TAG_KEY = "dubbo.tag";
private static final Set<String> UNLOADING_KEYS;
@@ -138,7 +146,19 @@ public class ContextFilter implements Filter, Filter.Listener {
@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
// pass attachments to result
- appResponse.addObjectAttachments(RpcContext.getServerContext().getObjectAttachments());
+ Map<String, Object> attachments = RpcContext.getServerContext().getObjectAttachments();
+ try {
+ appResponse.addObjectAttachments(attachments);
+ } catch (ConcurrentModificationException e) {
+ logger.error(Thread.currentThread().getName() + " " + attachments);
+ ThreadMXBean bean = ManagementFactory.getThreadMXBean();
+ ThreadInfo[] infos = bean.dumpAllThreads(true, true);
+ logger.error(Arrays.stream(infos).map(Object::toString)
+ .collect(Collectors.joining()));
+
+ logger.error(e);
+ throw e;
+ }
}
@Override