You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by cr...@apache.org on 2022/06/15 09:40:44 UTC
[dubbo] branch 3.0 updated: [3.0] Add safe foreach in RpcInvocation & Revert synchronizedMap in RpcInvocation (#10160)
This is an automated email from the ASF dual-hosted git repository.
crazyhzm 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 89863e048d [3.0] Add safe foreach in RpcInvocation & Revert synchronizedMap in RpcInvocation (#10160)
89863e048d is described below
commit 89863e048d745b5c655a6b859347b32939b743db
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Wed Jun 15 17:40:20 2022 +0800
[3.0] Add safe foreach in RpcInvocation & Revert synchronizedMap in RpcInvocation (#10160)
* revert
* [3.0] Add safe foreach in RpcInvocation & Revert synchronizedMap in RpcInvocation
* fix ut
---
.../cluster/router/mock/MockInvokersSelector.java | 2 +-
.../rpc/cluster/directory/MockDirInvocation.java | 11 ++
.../router/mock/MockInvokersSelectorTest.java | 6 +-
.../java/com/alibaba/dubbo/rpc/Invocation.java | 12 ++
.../org/apache/dubbo/service/MockInvocation.java | 11 ++
.../main/java/org/apache/dubbo/rpc/Invocation.java | 7 +
.../java/org/apache/dubbo/rpc/RpcInvocation.java | 216 +++++++++++++++------
.../dubbo/rpc/filter/ProfilerServerFilter.java | 6 +-
.../org/apache/dubbo/rpc/filter/TokenFilter.java | 5 +-
.../apache/dubbo/rpc/filter/TokenHeaderFilter.java | 5 +-
.../apache/dubbo/rpc/protocol/AbstractInvoker.java | 2 +-
.../org/apache/dubbo/rpc/proxy/InvocationUtil.java | 6 +-
.../apache/dubbo/rpc/filter/TokenFilterTest.java | 4 +-
.../rpc/protocol/dubbo/CallbackServiceCodec.java | 2 +-
.../protocol/dubbo/DecodeableRpcInvocation.java | 8 +-
.../dubbo/rpc/protocol/dubbo/DubboProtocol.java | 20 +-
.../rpc/protocol/dubbo/DubboCountCodecTest.java | 4 +-
.../dubbo/rpc/protocol/injvm/InjvmInvoker.java | 4 +-
.../dubbo/rpc/protocol/tri/TripleInvoker.java | 15 +-
19 files changed, 226 insertions(+), 120 deletions(-)
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
index b031c00338..1ea813c598 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
@@ -65,7 +65,7 @@ public class MockInvokersSelector<T> extends AbstractStateRouter<T> {
}
return invokers.and(normalInvokers);
} else {
- String value = (String) invocation.getObjectAttachments().get(INVOCATION_NEED_MOCK);
+ String value = (String) invocation.getObjectAttachmentWithoutConvert(INVOCATION_NEED_MOCK);
if (value == null) {
if (needToPrintMessage) {
messageHolder.set("invocation.need.mock not set. Return normal Invokers.");
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java
index 75ad1ccc62..246c7bdeec 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Consumer;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -84,6 +85,16 @@ public class MockDirInvocation implements Invocation {
return attachments;
}
+ @Override
+ public Map<String, Object> copyObjectAttachments() {
+ return new HashMap<>(attachments);
+ }
+
+ @Override
+ public void foreachAttachment(Consumer<Map.Entry<String, Object>> consumer) {
+ attachments.entrySet().forEach(consumer);
+ }
+
@Override
public void setAttachment(String key, String value) {
setObjectAttachment(key, value);
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java
index 6798afd4ff..7d6096df1b 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java
@@ -27,9 +27,7 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
@@ -59,9 +57,7 @@ public class MockInvokersSelectorTest {
Assertions.assertTrue(invokers.contains(invoker3));
// rpcInvocation have an attached "invocation.need.mock" parameter, so it will filter out the invoker whose protocol is mock
- Map<String,Object> attachments = new HashMap<>();
- attachments.put(INVOCATION_NEED_MOCK,"true");
- Mockito.when(rpcInvocation.getObjectAttachments()).thenReturn(attachments);
+ Mockito.when(rpcInvocation.getObjectAttachmentWithoutConvert(INVOCATION_NEED_MOCK)).thenReturn("true");
invokers = selector.route(providers.clone(), consumerURL, rpcInvocation, false, new Holder<>());
Assertions.assertEquals(invokers.size(),2);
Assertions.assertTrue(invokers.contains(invoker1));
diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java
index 92e483187a..c016e3b0ea 100644
--- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java
+++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java
@@ -20,7 +20,9 @@ package com.alibaba.dubbo.rpc;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
+import java.util.function.Consumer;
@Deprecated
public interface Invocation extends org.apache.dubbo.rpc.Invocation {
@@ -107,6 +109,16 @@ public interface Invocation extends org.apache.dubbo.rpc.Invocation {
return Collections.emptyMap();
}
+ @Override
+ default Map<String, Object> copyObjectAttachments() {
+ return new HashMap<>(getObjectAttachments());
+ }
+
+ @Override
+ default void foreachAttachment(Consumer<Map.Entry<String, Object>> consumer) {
+ getObjectAttachments().entrySet().forEach(consumer);
+ }
+
@Override
default Object getObjectAttachment(String key) {
return null;
diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java b/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java
index 532f6bde44..233260f3a2 100644
--- a/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java
+++ b/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Consumer;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -88,6 +89,16 @@ public class MockInvocation implements Invocation {
return attachments;
}
+ @Override
+ public Map<String, Object> copyObjectAttachments() {
+ return new HashMap<>(attachments);
+ }
+
+ @Override
+ public void foreachAttachment(Consumer<Map.Entry<String, Object>> consumer) {
+ attachments.entrySet().forEach(consumer);
+ }
+
@Override
public void setAttachment(String key, String value) {
setObjectAttachment(key, value);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
index 3a4e21613d..d2d8f64365 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.stream.Stream;
/**
@@ -91,6 +92,12 @@ public interface Invocation {
@Experimental("Experiment api for supporting Object transmission")
Map<String, Object> getObjectAttachments();
+ @Experimental("Experiment api for supporting Object transmission")
+ Map<String, Object> copyObjectAttachments();
+
+ @Experimental("Experiment api for supporting Object transmission")
+ void foreachAttachment(Consumer<Map.Entry<String, Object>> consumer);
+
void setAttachment(String key, String value);
@Experimental("Experiment api for supporting Object transmission")
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 9e4244254c..f5ec9fd064 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
@@ -17,7 +17,6 @@
package org.apache.dubbo.rpc;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.FrameworkModel;
@@ -36,6 +35,9 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
import java.util.stream.Stream;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
@@ -75,6 +77,8 @@ public class RpcInvocation implements Invocation, Serializable {
*/
private Map<String, Object> attachments;
+ private transient Lock attachmentLock = new ReentrantLock();
+
/**
* Only used on the caller side, will not appear on the wire.
*/
@@ -113,9 +117,7 @@ public class RpcInvocation implements Invocation, Serializable {
public RpcInvocation(Invocation invocation, Invoker<?> invoker) {
this(invocation.getTargetServiceUniqueName(), invocation.getServiceModel(), invocation.getMethodName(), invocation.getServiceName(),
invocation.getProtocolServiceKey(), invocation.getParameterTypes(), invocation.getArguments(),
- CollectionUtils.isEmptyMap(invocation.getObjectAttachments()) ?
- Collections.synchronizedMap(new HashMap<>()) : Collections.synchronizedMap(invocation.getObjectAttachments()),
- invocation.getInvoker(), invocation.getAttributes(),
+ invocation.copyObjectAttachments(), invocation.getInvoker(), invocation.getAttributes(),
invocation instanceof RpcInvocation ? ((RpcInvocation) invocation).getInvokeMode() : null);
if (invoker != null) {
URL url = invoker.getUrl();
@@ -243,7 +245,7 @@ public class RpcInvocation implements Invocation, Serializable {
this.protocolServiceKey = protocolServiceKey;
this.parameterTypes = parameterTypes == null ? new Class<?>[0] : parameterTypes;
this.arguments = arguments == null ? new Object[0] : arguments;
- this.attachments = attachments == null ? Collections.synchronizedMap(new HashMap<>()) : attachments;
+ this.attachments = attachments == null ? new HashMap<>() : attachments;
this.attributes = attributes == null ? Collections.synchronizedMap(new HashMap<>()) : attributes;
this.invoker = invoker;
initParameterDesc();
@@ -380,11 +382,46 @@ public class RpcInvocation implements Invocation, Serializable {
@Override
public Map<String, Object> getObjectAttachments() {
- return attachments;
+ try {
+ attachmentLock.lock();
+ return attachments;
+ } finally {
+ attachmentLock.unlock();
+ }
+ }
+
+ @Override
+ public Map<String, Object> copyObjectAttachments() {
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return new HashMap<>();
+ }
+ return new HashMap<>(attachments);
+ } finally {
+ attachmentLock.unlock();
+ }
+ }
+
+ @Override
+ public void foreachAttachment(Consumer<Map.Entry<String, Object>> consumer) {
+ try {
+ attachmentLock.lock();
+ if (attachments != null) {
+ attachments.entrySet().forEach(consumer);
+ }
+ } finally {
+ attachmentLock.unlock();
+ }
}
public void setObjectAttachments(Map<String, Object> attachments) {
- this.attachments = attachments == null ? Collections.synchronizedMap(new HashMap<>()) : attachments;
+ try {
+ attachmentLock.lock();
+ this.attachments = attachments == null ? new HashMap<>() : attachments;
+ } finally {
+ attachmentLock.unlock();
+ }
}
@Override
@@ -395,12 +432,22 @@ public class RpcInvocation implements Invocation, Serializable {
@Deprecated
@Override
public Map<String, String> getAttachments() {
- return new AttachmentsAdapter.ObjectToStringMap(attachments);
+ try {
+ attachmentLock.lock();
+ return new AttachmentsAdapter.ObjectToStringMap(attachments);
+ } finally {
+ attachmentLock.unlock();
+ }
}
@Deprecated
public void setAttachments(Map<String, String> attachments) {
- this.attachments = attachments == null ? Collections.synchronizedMap(new HashMap<>()) : new HashMap<>(attachments);
+ try {
+ attachmentLock.lock();
+ this.attachments = attachments == null ? new HashMap<>() : new HashMap<>(attachments);
+ } finally {
+ attachmentLock.unlock();
+ }
}
@Override
@@ -410,10 +457,15 @@ public class RpcInvocation implements Invocation, Serializable {
@Override
public void setObjectAttachment(String key, Object value) {
- if (attachments == null) {
- attachments = Collections.synchronizedMap(new HashMap<>());
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ attachments = new HashMap<>();
+ }
+ attachments.put(key, value);
+ } finally {
+ attachmentLock.unlock();
}
- attachments.put(key, value);
}
@Override
@@ -428,33 +480,48 @@ public class RpcInvocation implements Invocation, Serializable {
@Override
public void setObjectAttachmentIfAbsent(String key, Object value) {
- if (attachments == null) {
- attachments = Collections.synchronizedMap(new HashMap<>());
- }
- if (!attachments.containsKey(key)) {
- attachments.put(key, value);
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ attachments = new HashMap<>();
+ }
+ if (!attachments.containsKey(key)) {
+ attachments.put(key, value);
+ }
+ } finally {
+ attachmentLock.unlock();
}
}
@Deprecated
public void addAttachments(Map<String, String> attachments) {
- if (attachments == null) {
- return;
- }
- if (this.attachments == null) {
- this.attachments = Collections.synchronizedMap(new HashMap<>());
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return;
+ }
+ if (this.attachments == null) {
+ this.attachments = new HashMap<>();
+ }
+ this.attachments.putAll(attachments);
+ } finally {
+ attachmentLock.unlock();
}
- this.attachments.putAll(attachments);
}
public void addObjectAttachments(Map<String, Object> attachments) {
- if (attachments == null) {
- return;
- }
- if (this.attachments == null) {
- this.attachments = Collections.synchronizedMap(new HashMap<>());
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return;
+ }
+ if (this.attachments == null) {
+ this.attachments = new HashMap<>();
+ }
+ this.attachments.putAll(attachments);
+ } finally {
+ attachmentLock.unlock();
}
- this.attachments.putAll(attachments);
}
@Deprecated
@@ -479,65 +546,90 @@ public class RpcInvocation implements Invocation, Serializable {
@Override
@Deprecated
public String getAttachment(String key) {
- if (attachments == null) {
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return null;
+ }
+ Object value = attachments.get(key);
+ if (value instanceof String) {
+ return (String) value;
+ }
return null;
+ } finally {
+ attachmentLock.unlock();
}
- Object value = attachments.get(key);
- if (value instanceof String) {
- return (String) value;
- }
- return null;
}
@Override
public Object getObjectAttachment(String key) {
- if (attachments == null) {
- return null;
- }
- final Object val = attachments.get(key);
- if (val != null) {
- return val;
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return null;
+ }
+ final Object val = attachments.get(key);
+ if (val != null) {
+ return val;
+ }
+ return attachments.get(key.toLowerCase(Locale.ROOT));
+ } finally {
+ attachmentLock.unlock();
}
- return attachments.get(key.toLowerCase(Locale.ROOT));
}
@Override
@Deprecated
public String getAttachment(String key, String defaultValue) {
- if (attachments == null) {
- return defaultValue;
- }
- Object value = attachments.get(key);
- if (value instanceof String) {
- String strValue = (String) value;
- if (StringUtils.isEmpty(strValue)) {
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
return defaultValue;
- } else {
- return strValue;
}
+ Object value = attachments.get(key);
+ if (value instanceof String) {
+ String strValue = (String) value;
+ if (StringUtils.isEmpty(strValue)) {
+ return defaultValue;
+ } else {
+ return strValue;
+ }
+ }
+ return defaultValue;
+ } finally {
+ attachmentLock.unlock();
}
- return defaultValue;
}
@Deprecated
@Override
public Object getObjectAttachment(String key, Object defaultValue) {
- if (attachments == null) {
- return defaultValue;
- }
- Object value = attachments.get(key);
- if (value == null) {
- return defaultValue;
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return defaultValue;
+ }
+ Object value = attachments.get(key);
+ if (value == null) {
+ return defaultValue;
+ }
+ return value;
+ } finally {
+ attachmentLock.unlock();
}
- return value;
}
@Override
public Object getObjectAttachmentWithoutConvert(String key) {
- if (attachments == null) {
- return null;
+ try {
+ attachmentLock.lock();
+ if (attachments == null) {
+ return null;
+ }
+ return attachments.get(key);
+ } finally {
+ attachmentLock.unlock();
}
- return attachments.get(key);
}
public Class<?> getReturnType() {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ProfilerServerFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ProfilerServerFilter.java
index f1d8d119a3..5596bf30f7 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ProfilerServerFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ProfilerServerFilter.java
@@ -30,8 +30,6 @@ import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
-import java.util.Map;
-
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
@@ -92,9 +90,9 @@ public class ProfilerServerFilter implements Filter, BaseFilter.Listener {
if (((usage / (1000_000L * ProfilerSwitch.getWarnPercent())) > timeout) && timeout != -1) {
StringBuilder attachment = new StringBuilder();
- for (Map.Entry<String, Object> entry : invocation.getObjectAttachments().entrySet()) {
+ invocation.foreachAttachment((entry) -> {
attachment.append(entry.getKey()).append("=").append(entry.getValue()).append(";\n");
- }
+ });
logger.warn(String.format("[Dubbo-Provider] execute service %s#%s cost %d.%06d ms, this invocation almost (maybe already) timeout. Timeout: %dms\n" +
"client: %s\n" +
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenFilter.java
index 3e5616b041..056d27e6a1 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenFilter.java
@@ -26,8 +26,6 @@ import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
-import java.util.Map;
-
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
/**
@@ -45,8 +43,7 @@ public class TokenFilter implements Filter {
String token = invoker.getUrl().getParameter(TOKEN_KEY);
if (ConfigUtils.isNotEmpty(token)) {
Class<?> serviceType = invoker.getInterface();
- Map<String, Object> attachments = inv.getObjectAttachments();
- String remoteToken = (attachments == null ? null : (String) attachments.get(TOKEN_KEY));
+ String remoteToken = (String) inv.getObjectAttachmentWithoutConvert(TOKEN_KEY);
if (!token.equals(remoteToken)) {
throw new RpcException("Invalid token! Forbid invoke remote service " + serviceType + " method " + inv.getMethodName() +
"() from consumer " + RpcContext.getServiceContext().getRemoteHost() + " to provider " +
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenHeaderFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenHeaderFilter.java
index 63b00512bc..d72b790a47 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenHeaderFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TokenHeaderFilter.java
@@ -24,8 +24,6 @@ import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.RpcInvocation;
-import java.util.Map;
-
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
import static org.apache.dubbo.rpc.RpcException.FORBIDDEN_EXCEPTION;
@@ -36,8 +34,7 @@ public class TokenHeaderFilter implements HeaderFilter {
String token = invoker.getUrl().getParameter(TOKEN_KEY);
if (ConfigUtils.isNotEmpty(token)) {
Class<?> serviceType = invoker.getInterface();
- Map<String, Object> attachments = invocation.getObjectAttachments();
- String remoteToken = (attachments == null ? null : (String) attachments.get(TOKEN_KEY));
+ String remoteToken = (String) invocation.getObjectAttachmentWithoutConvert(TOKEN_KEY);
if (!token.equals(remoteToken)) {
throw new RpcException(FORBIDDEN_EXCEPTION, "Forbid invoke remote service " + serviceType + " method " + invocation.getMethodName() +
"() from consumer " + RpcContext.getServiceContext().getRemoteHost() + " to provider " +
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java
index b8c389f289..71247a5523 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java
@@ -259,7 +259,7 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
* must call {@link java.util.concurrent.CompletableFuture#get(long, TimeUnit)} because
* {@link java.util.concurrent.CompletableFuture#get()} was proved to have serious performance drop.
*/
- Object timeout = invocation.getObjectAttachment(TIMEOUT_KEY);
+ Object timeout = invocation.getObjectAttachmentWithoutConvert(TIMEOUT_KEY);
if (timeout instanceof Integer) {
asyncResult.get((Integer) timeout, TimeUnit.MILLISECONDS);
} else {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvocationUtil.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvocationUtil.java
index 2df39f9d3c..9d75590624 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvocationUtil.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvocationUtil.java
@@ -27,8 +27,6 @@ import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.RpcServiceContext;
-import java.util.Map;
-
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
@@ -69,9 +67,9 @@ public class InvocationUtil {
long usage = bizProfiler.getEndTime() - bizProfiler.getStartTime();
if ((usage / (1000_000L * ProfilerSwitch.getWarnPercent())) > timeout) {
StringBuilder attachment = new StringBuilder();
- for (Map.Entry<String, Object> entry : rpcInvocation.getObjectAttachments().entrySet()) {
+ rpcInvocation.foreachAttachment((entry) -> {
attachment.append(entry.getKey()).append("=").append(entry.getValue()).append(";\n");
- }
+ });
logger.warn(String.format(
"[Dubbo-Consumer] execute service %s#%s cost %d.%06d ms, this invocation almost (maybe already) timeout. Timeout: %dms\n" + "invocation context:\n%s" + "thread info: \n%s",
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java
index 1adb7a1727..c31cd67729 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java
@@ -47,10 +47,8 @@ public class TokenFilterTest {
when(invoker.getUrl()).thenReturn(url);
when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
- Map<String, Object> attachments = new HashMap<>();
- attachments.put(TOKEN_KEY, token);
Invocation invocation = Mockito.mock(Invocation.class);
- when(invocation.getObjectAttachments()).thenReturn(attachments);
+ when(invocation.getObjectAttachmentWithoutConvert(TOKEN_KEY)).thenReturn(token);
Result result = tokenFilter.invoke(invoker, invocation);
Assertions.assertEquals("result", result.getValue());
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java
index 332dff5cac..38acb87247 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java
@@ -116,7 +116,7 @@ public class CallbackServiceCodec {
params.put(IS_SERVER_KEY, Boolean.FALSE.toString());
// mark it's a callback, for troubleshooting
params.put(IS_CALLBACK_SERVICE, Boolean.TRUE.toString());
- String group = (inv == null ? null : (String) inv.getObjectAttachment(GROUP_KEY));
+ String group = (inv == null ? null : (String) inv.getObjectAttachmentWithoutConvert(GROUP_KEY));
if (group != null && group.length() > 0) {
params.put(GROUP_KEY, group);
}
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java
index b63f86cdb8..1f7de2e538 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java
@@ -43,7 +43,6 @@ import org.apache.dubbo.rpc.support.RpcUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -217,12 +216,7 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec
Map<String, Object> map = in.readAttachments();
if (CollectionUtils.isNotEmptyMap(map)) {
- Map<String, Object> attachment = getObjectAttachments();
- if (attachment == null) {
- attachment = new HashMap<>(map.size());
- }
- attachment.putAll(map);
- setObjectAttachments(attachment);
+ addObjectAttachments(map);
}
//decode argument ,may be callback
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
index 5e01fc42f0..dcff5f4692 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
@@ -122,7 +122,7 @@ public class DubboProtocol extends AbstractProtocol {
Thread.currentThread().setContextClassLoader(invoker.getUrl().getServiceModel().getClassLoader());
}
// need to consider backward-compatibility if it's a callback
- if (Boolean.TRUE.toString().equals(inv.getObjectAttachments().get(IS_CALLBACK_SERVICE_INVOKE))) {
+ if (Boolean.TRUE.toString().equals(inv.getObjectAttachmentWithoutConvert(IS_CALLBACK_SERVICE_INVOKE))) {
String methodsStr = invoker.getUrl().getParameters().get("methods");
boolean hasMethod = false;
if (methodsStr == null || !methodsStr.contains(",")) {
@@ -192,9 +192,9 @@ public class DubboProtocol extends AbstractProtocol {
} catch (RemotingException e) {
String serviceKey = serviceKey(
0,
- (String) invocation.getObjectAttachments().get(PATH_KEY),
- (String) invocation.getObjectAttachments().get(VERSION_KEY),
- (String) invocation.getObjectAttachments().get(GROUP_KEY)
+ (String) invocation.getObjectAttachmentWithoutConvert(PATH_KEY),
+ (String) invocation.getObjectAttachmentWithoutConvert(VERSION_KEY),
+ (String) invocation.getObjectAttachmentWithoutConvert(GROUP_KEY)
);
throw new RemotingException(channel, "The stub service[" + serviceKey + "] is not found, it may not be exported yet");
}
@@ -260,10 +260,10 @@ public class DubboProtocol extends AbstractProtocol {
boolean isCallBackServiceInvoke;
boolean isStubServiceInvoke;
int port = channel.getLocalAddress().getPort();
- String path = (String) inv.getObjectAttachments().get(PATH_KEY);
+ String path = (String) inv.getObjectAttachmentWithoutConvert(PATH_KEY);
//if it's stub service on client side(after enable stubevent, usually is set up onconnect or ondisconnect method)
- isStubServiceInvoke = Boolean.TRUE.toString().equals(inv.getObjectAttachments().get(STUB_EVENT_KEY));
+ isStubServiceInvoke = Boolean.TRUE.toString().equals(inv.getObjectAttachmentWithoutConvert(STUB_EVENT_KEY));
if (isStubServiceInvoke) {
//when a stub service export to local, it usually can't be exposed to port
port = 0;
@@ -272,15 +272,15 @@ public class DubboProtocol extends AbstractProtocol {
// if it's callback service on client side
isCallBackServiceInvoke = isClientSide(channel) && !isStubServiceInvoke;
if (isCallBackServiceInvoke) {
- path += "." + inv.getObjectAttachments().get(CALLBACK_SERVICE_KEY);
- inv.getObjectAttachments().put(IS_CALLBACK_SERVICE_INVOKE, Boolean.TRUE.toString());
+ path += "." + inv.getObjectAttachmentWithoutConvert(CALLBACK_SERVICE_KEY);
+ inv.setObjectAttachment(IS_CALLBACK_SERVICE_INVOKE, Boolean.TRUE.toString());
}
String serviceKey = serviceKey(
port,
path,
- (String) inv.getObjectAttachments().get(VERSION_KEY),
- (String) inv.getObjectAttachments().get(GROUP_KEY)
+ (String) inv.getObjectAttachmentWithoutConvert(VERSION_KEY),
+ (String) inv.getObjectAttachmentWithoutConvert(GROUP_KEY)
);
DubboExporter<?> exporter = (DubboExporter<?>) exporterMap.get(serviceKey);
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodecTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodecTest.java
index 6ac3acffe6..b531bb1aa0 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodecTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodecTest.java
@@ -61,7 +61,7 @@ public class DubboCountCodecTest {
}
MultiMessage multiMessage = (MultiMessage) dubboCountCodec.decode(channel, buffer);
- Assertions.assertEquals(multiMessage.size(), 18);
+ Assertions.assertEquals(multiMessage.size(), 20);
int requestCount = 0;
int responseCount = 0;
Iterator iterator = multiMessage.iterator();
@@ -78,7 +78,7 @@ public class DubboCountCodecTest {
}
}
Assertions.assertEquals(requestCount, 10);
- Assertions.assertEquals(responseCount, 8);
+ Assertions.assertEquals(responseCount, 10);
}
}
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 1dcc98806d..719e036d84 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
@@ -203,7 +203,7 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
// generic invoke, skip copy arguments
RpcInvocation copiedInvocation = new RpcInvocation(invocation.getTargetServiceUniqueName(),
providerServiceModel, methodName, invocation.getServiceName(), invocation.getProtocolServiceKey(),
- invocation.getParameterTypes(), invocation.getArguments(), new HashMap<>(invocation.getObjectAttachments()),
+ invocation.getParameterTypes(), invocation.getArguments(), invocation.copyObjectAttachments(),
invocation.getInvoker(), new HashMap<>(),
invocation instanceof RpcInvocation ? ((RpcInvocation) invocation).getInvokeMode() : null);
copiedInvocation.setInvoker(invoker);
@@ -233,7 +233,7 @@ 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()),
+ pts, realArgument, invocation.copyObjectAttachments(),
invocation.getInvoker(), new HashMap<>(),
invocation instanceof RpcInvocation ? ((RpcInvocation) invocation).getInvokeMode() : null);
copiedInvocation.setInvoker(invoker);
diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java
index ef0afe55a9..6146fc6232 100644
--- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java
@@ -51,7 +51,6 @@ import org.apache.dubbo.rpc.support.RpcUtils;
import io.netty.util.AsciiString;
import java.util.Arrays;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -260,16 +259,12 @@ public class TripleInvoker<T> extends AbstractInvoker<T> {
if (timeout != null) {
meta.timeout = timeout + "m";
}
- final Map<String, Object> objectAttachments = invocation.getObjectAttachments();
- if (objectAttachments != null) {
- String application = (String) objectAttachments.get(CommonConstants.APPLICATION_KEY);
- if (application == null) {
- application = (String) objectAttachments.get(
- CommonConstants.REMOTE_APPLICATION_KEY);
- }
- meta.application = application;
- meta.attachments = objectAttachments;
+ String application = (String) invocation.getObjectAttachmentWithoutConvert(CommonConstants.APPLICATION_KEY);
+ if (application == null) {
+ application = (String) invocation.getObjectAttachmentWithoutConvert(CommonConstants.REMOTE_APPLICATION_KEY);
}
+ meta.application = application;
+ meta.attachments = invocation.getObjectAttachments();
return meta;
}