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/12/16 14:39:43 UTC

[dubbo] branch 3.0-metadata-refactor updated: init metadata info before use on the consumer side

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

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


The following commit(s) were added to refs/heads/3.0-metadata-refactor by this push:
     new 2eeda66  init metadata info before use on the consumer side
2eeda66 is described below

commit 2eeda666d3b45e154e85e908f02b0db5440bd881
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Dec 16 22:36:49 2021 +0800

    init metadata info before use on the consumer side
---
 .../org/apache/dubbo/metadata/MetadataInfo.java    | 91 +++++++++++++++-------
 .../registry/client/AbstractServiceDiscovery.java  |  1 +
 .../metadata/ServiceInstanceMetadataUtils.java     | 15 +---
 .../StandardMetadataServiceURLBuilder.java         | 16 +++-
 4 files changed, 82 insertions(+), 41 deletions(-)

diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
index 5221ed2..0d10238 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
@@ -64,6 +64,8 @@ public class MetadataInfo implements Serializable {
     private String revision;
     private Map<String, ServiceInfo> services;
 
+    private volatile AtomicBoolean initiated = new AtomicBoolean(false);
+
     // used at runtime
     private transient final Map<String, String> extendParams;
     private transient final Map<String, String> instanceParams;
@@ -88,9 +90,25 @@ public class MetadataInfo implements Serializable {
         this.instanceParams = new ConcurrentHashMap<>();
     }
 
+    /**
+     * Initialize is needed when MetadataInfo is created from deserialization on the consumer side before being used for RPC call.
+     */
+    public void init() {
+        if (!initiated.compareAndSet(false, true)) {
+            return;
+        }
+        if (CollectionUtils.isNotEmptyMap(services)) {
+            services.forEach((_k, serviceInfo) -> {
+                serviceInfo.init();
+            });
+        }
+    }
+
     public synchronized void addService(URL url) {
         // fixme, pass in application mode context during initialization of MetadataInfo.
-        this.loader = url.getOrDefaultApplicationModel().getExtensionLoader(MetadataParamsFilter.class);
+        if (this.loader == null) {
+            this.loader = url.getOrDefaultApplicationModel().getExtensionLoader(MetadataParamsFilter.class);
+        }
         List<MetadataParamsFilter> filters = loader.getActivateExtension(url, "params-filter");
         // generate service level metadata
         ServiceInfo serviceInfo = new ServiceInfo(url, filters);
@@ -335,17 +353,17 @@ public class MetadataInfo implements Serializable {
         private Map<String, String> params;
 
         // params configured on consumer side,
-        private transient Map<String, String> consumerParams;
+        private volatile transient Map<String, String> consumerParams;
         // cached method params
-        private transient Map<String, Map<String, String>> methodParams;
-        private transient Map<String, Map<String, String>> consumerMethodParams;
+        private volatile transient Map<String, Map<String, String>> methodParams;
+        private volatile transient Map<String, Map<String, String>> consumerMethodParams;
         // cached numbers
-        private transient Map<String, Number> numbers;
-        private transient Map<String, Map<String, Number>> methodNumbers;
+        private volatile transient Map<String, Number> numbers;
+        private volatile transient Map<String, Map<String, Number>> methodNumbers;
         // service + group + version
-        private transient String serviceKey;
+        private volatile transient String serviceKey;
         // service + group + version + protocol
-        private transient String matchKey;
+        private volatile transient String matchKey;
 
         private transient URL url;
 
@@ -385,6 +403,9 @@ public class MetadataInfo implements Serializable {
                 }
             }
             this.params = params;
+            // initialize method params caches.
+            this.methodParams = URLParam.initMethodParameters(params);
+            this.consumerMethodParams = URLParam.initMethodParameters(consumerParams);
         }
 
         public ServiceInfo(String name, String group, String version, String protocol, String path, Map<String, String> params) {
@@ -395,10 +416,24 @@ public class MetadataInfo implements Serializable {
             this.path = path;
             this.params = params == null ? new ConcurrentHashMap<>() : params;
 
-            this.serviceKey = URL.buildKey(name, group, version);
+            this.serviceKey = buildServiceKey(name, group, version);
             this.matchKey = buildMatchKey();
         }
 
+        /**
+         * Initialize necessary caches right after deserialization on the consumer side
+         */
+        protected void init() {
+            buildMatchKey();
+            buildServiceKey(name, group, version);
+            // init method params
+            this.methodParams = URLParam.initMethodParameters(params);
+            // Actually, consumer params is empty after deserialization on the consumer side, so no need to initialize.
+            // Check how InstanceAddressURL operates on consumer url for more detail.
+//            this.consumerMethodParams = URLParam.initMethodParameters(consumerParams);
+            // no need to init numbers for it's only for cache purpose
+        }
+
         public String getMatchKey() {
             if (matchKey != null) {
                 return matchKey;
@@ -415,11 +450,16 @@ public class MetadataInfo implements Serializable {
             return matchKey;
         }
 
+        private String buildServiceKey(String name, String group, String version) {
+            this.serviceKey = URL.buildKey(name, group, version);
+            return this.serviceKey;
+        }
+
         public String getServiceKey() {
             if (serviceKey != null) {
                 return serviceKey;
             }
-            this.serviceKey = URL.buildKey(name, group, version);
+            buildServiceKey(name, group, version);
             return serviceKey;
         }
 
@@ -495,11 +535,6 @@ public class MetadataInfo implements Serializable {
         }
 
         public String getMethodParameter(String method, String key, String defaultValue) {
-            if (methodParams == null) {
-                methodParams = URLParam.initMethodParameters(params);
-                consumerMethodParams = URLParam.initMethodParameters(consumerParams);
-            }
-
             String value = getMethodParameter(method, key, consumerMethodParams);
             if (value != null) {
                 return value;
@@ -510,11 +545,13 @@ public class MetadataInfo implements Serializable {
 
         private String getMethodParameter(String method, String key, Map<String, Map<String, String>> map) {
             String value = null;
-            if (map != null) {
-                Map<String, String> keyMap = map.get(method);
-                if (keyMap != null) {
-                    value = keyMap.get(key);
-                }
+            if (map == null) {
+                return value;
+            }
+
+            Map<String, String> keyMap = map.get(method);
+            if (keyMap != null) {
+                value = keyMap.get(key);
             }
             return value;
         }
@@ -525,12 +562,8 @@ public class MetadataInfo implements Serializable {
         }
 
         public boolean hasMethodParameter(String method) {
-            if (methodParams == null) {
-                methodParams = URLParam.initMethodParameters(params);
-                consumerMethodParams = URLParam.initMethodParameters(consumerParams);
-            }
-
-            return consumerMethodParams.containsKey(method) || methodParams.containsKey(method);
+            return (consumerMethodParams != null && consumerMethodParams.containsKey(method))
+                || (methodParams != null && methodParams.containsKey(method));
         }
 
         public String toDescString() {
@@ -541,18 +574,24 @@ public class MetadataInfo implements Serializable {
             if (consumerParams != null) {
                 this.consumerParams.put(key, value);
             }
+            // refresh method params
+            consumerMethodParams = URLParam.initMethodParameters(consumerParams);
         }
 
         public void addParameterIfAbsent(String key, String value) {
             if (consumerParams != null) {
                 this.consumerParams.putIfAbsent(key, value);
             }
+            // refresh method params
+            consumerMethodParams = URLParam.initMethodParameters(consumerParams);
         }
 
         public void addConsumerParams(Map<String, String> params) {
             // copy once for one service subscription
             if (consumerParams == null) {
                 consumerParams = new ConcurrentHashMap<>(params);
+                // init method params
+                consumerMethodParams = URLParam.initMethodParameters(consumerParams);
             }
         }
 
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
index f70fcac..517ebaf 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
@@ -158,6 +158,7 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery {
             metadata = MetadataUtils.getRemoteMetadata(revision, instance, metadataReport);
 
             if (metadata != MetadataInfo.EMPTY) {// succeeded
+                metadata.init();
                 break;
             } else {// failed
                 if (triedTimes > 0) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
index 361b83d..fe4c38e 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
@@ -37,7 +37,6 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import static java.util.Collections.emptyMap;
 import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -93,19 +92,7 @@ public class ServiceInstanceMetadataUtils {
 
     public static final String INSTANCE_REVISION_UPDATED_KEY = "dubbo.instance.revision.updated";
 
-    private static final Gson gson = new Gson();
-
-    /**
-     * Get the multiple {@link URL urls'} parameters of {@link MetadataService MetadataService's} Metadata
-     *
-     * @param serviceInstance the instance of {@link ServiceInstance}
-     * @return non-null {@link Map}, the key is {@link URL#getProtocol() the protocol of URL}, the value is
-     */
-    public static Map<String, String> getMetadataServiceURLsParams(ServiceInstance serviceInstance) {
-        Map<String, String> metadata = serviceInstance.getMetadata();
-        String param = metadata.get(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME);
-        return isBlank(param) ? emptyMap() : (Map) gson.fromJson(param,Map.class);
-    }
+    public static final Gson gson = new Gson();
 
     public static String getMetadataServiceParameter(URL url) {
         if (url == null) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
index 3c94a92..2b14326 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
@@ -30,6 +30,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import static java.util.Collections.emptyMap;
 import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
 import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -38,9 +39,10 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.utils.StringUtils.isBlank;
 import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_METADATA_TIMEOUT_VALUE;
 import static org.apache.dubbo.metadata.MetadataConstants.METADATA_PROXY_TIMEOUT_KEY;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataServiceURLsParams;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME;
 
 /**
  * Standard Dubbo provider enabling introspection service discovery mode.
@@ -140,4 +142,16 @@ public class StandardMetadataServiceURLBuilder implements MetadataServiceURLBuil
 
         return urlBuilder.build();
     }
+
+    /**
+     * Get the multiple {@link URL urls'} parameters of {@link MetadataService MetadataService's} Metadata
+     *
+     * @param serviceInstance the instance of {@link ServiceInstance}
+     * @return non-null {@link Map}, the key is {@link URL#getProtocol() the protocol of URL}, the value is
+     */
+    private Map<String, String> getMetadataServiceURLsParams(ServiceInstance serviceInstance) {
+        Map<String, String> metadata = serviceInstance.getMetadata();
+        String param = metadata.get(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME);
+        return isBlank(param) ? emptyMap() : (Map) ServiceInstanceMetadataUtils.gson.fromJson(param,Map.class);
+    }
 }