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

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


The following commit(s) were added to refs/heads/dev-metadata by this push:
     new 1646e6c  Enhancements for router chain: 1. make route cache building 
in RouterChain thread-safe. 2. clear generated routers when urls change. 3. 
clear invokers in route cache when provider list in notification is empty. 4. 
add name for each router.
1646e6c is described below

commit 1646e6c733b03d34d73b20946e691a9123342137
Author: ken.lj <[email protected]>
AuthorDate: Fri Oct 19 14:25:27 2018 +0800

    Enhancements for router chain:
    1. make route cache building in RouterChain thread-safe.
    2. clear generated routers when urls change.
    3. clear invokers in route cache when provider list in notification is 
empty.
    4. add name for each router.
---
 .../org/apache/dubbo/rpc/cluster/RouterChain.java  | 70 ++++++++++++++++++----
 .../rpc/cluster/directory/AbstractDirectory.java   |  8 +--
 .../dubbo/rpc/cluster/router/AbstractRouter.java   | 14 ++---
 .../dubbo/rpc/cluster/router/InvokerTreeCache.java | 18 +++---
 .../cluster/router/condition/ConditionRouter.java  | 20 +++----
 .../condition/config/ConfigConditionRouter.java    | 45 ++++++++------
 .../config/ConfigConditionRouterFactory.java       |  2 +-
 .../cluster/router/mock/MockInvokersSelector.java  | 13 ++++
 .../rpc/cluster/router/script/ScriptRouter.java    | 19 +++---
 .../dubbo/rpc/cluster/router/tag/TagRouter.java    | 13 ++--
 .../rpc/cluster/router/tag/TagRouterFactory.java   |  2 +-
 dubbo-dependencies-bom/pom.xml                     |  1 +
 .../registry/integration/RegistryDirectory.java    |  4 +-
 13 files changed, 148 insertions(+), 81 deletions(-)

diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
index 179b2b9..e788754 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
@@ -27,29 +27,38 @@ import org.apache.dubbo.rpc.cluster.router.InvokerTreeCache;
 import org.apache.dubbo.rpc.cluster.router.TreeNode;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  *
  */
 public class RouterChain<T> {
 
+    // full list of addresses from registry, classified by method name.
     private Map<String, List<Invoker<T>>> fullMethodInvokers;
     private URL url;
 
+    // a tree-structured cache generated from the full address list after 
being filtered by all routers.
+    // it's aimed to improve performance, only routers explicitly specifies 
'runtime=true' will be executed when an RPC comes.
     private InvokerTreeCache<T> treeCache;
+    // containing all routers, reconstruct every time 'route://' urls change.
     private List<Router> routers;
+    // Fixed router instances: ConfigConditionRouter, TagRouter, e.g., the 
rule for each instance may change but the instance will never delete or 
recreate.
+    private List<Router> residentRouters;
 
     public static <T> RouterChain<T> buildChain(DynamicConfiguration 
dynamicConfiguration, URL url) {
         RouterChain<T> routerChain = new RouterChain<>(url);
         List<RouterFactory> extensionFactories = 
ExtensionLoader.getExtensionLoader(RouterFactory.class).getActivateExtension(dynamicConfiguration.getUrl(),
 (String[]) null);
-        extensionFactories.stream()
-                .map(factory -> factory.getRouter(dynamicConfiguration, url))
-                .forEach(router -> {
-                    routerChain.addRouter(router);
+        List<Router> routers = extensionFactories.stream()
+                .map(factory -> {
+                    Router router = factory.getRouter(dynamicConfiguration, 
url);
                     router.setRouterChain(routerChain);
-                });
+                    return router;
+                }).collect(Collectors.toList());
+        routerChain.setResidentRouters(routers);
         return routerChain;
     }
 
@@ -64,45 +73,84 @@ public class RouterChain<T> {
         this.url = url;
     }
 
+    /**
+     * the resident routers must have already been generated before 
notification of provider addresses.
+     *
+     * @param residentRouters
+     */
+    public void setResidentRouters(List<Router> residentRouters) {
+        this.residentRouters = residentRouters;
+        this.routers.addAll(residentRouters);
+        this.sort();
+    }
+
+    /**
+     * If we use route:// protocol in version before 2.7.0, each URL will 
generate a Router instance,
+     * so we should keep the routers up to date, that is, each time router 
URLs changes, we should update the routers list,
+     * only keep the residentRouters which are available all the time and the 
latest notified routers which are generated from URLs.
+     *
+     * @param generatedRouters
+     */
+    public void setGeneratedRouters(List<Router> generatedRouters) {
+        this.routers = new ArrayList<>();
+        this.routers.addAll(residentRouters);
+        this.routers.addAll(generatedRouters);
+        this.sort();
+        if (fullMethodInvokers != null) {
+            this.preRoute(fullMethodInvokers, url, null);
+        }
+    }
+
     public void addRouter(Router router) {
         this.routers.add(router);
+        this.sort();
     }
 
     public void sort() {
-
+        Collections.sort(routers);
     }
 
     /**
+     * Route cache building can be triggered in different threads, for 
example, registry notification and governance notification.
+     * So this operation should be synchronized.
      * @param methodInvokers
      * @param url
-     * @param invocation     TODO has not being used yet
+     * @param invocation     TODO has not been used yet
      */
     public void preRoute(Map<String, List<Invoker<T>>> methodInvokers, URL 
url, Invocation invocation) {
         if (CollectionUtils.isEmpty(routers)) {
+            treeCache.refreshTree(null);
             return;
         }
-        TreeNode root = treeCache.buildTree();
+        TreeNode<T> root = treeCache.buildRootNode();
         Router router = routers.get(0);
         methodInvokers.forEach((method, invokers) -> {
             TreeNode<T> node = new TreeNode<>("METHOD_ROUTER", "method", 
method, invokers, true);
             root.addChild(node);
             Invocation invocation1 = new RpcInvocation(method, new 
Class<?>[0], new Object[0]);
-            routeeee(router, 1, node, router.preRoute(invokers, url, 
invocation1), url, invocation1);
+            doRoute(router, 1, node, router.preRoute(invokers, url, 
invocation1), url, invocation1);
         });
+        treeCache.refreshTree(root);
     }
 
-    private void routeeee(Router router, int i, TreeNode parentNode, 
Map<String, List<Invoker<T>>> invokers, URL url, Invocation invocation) {
+    private void doRoute(Router router, int i, TreeNode parentNode, 
Map<String, List<Invoker<T>>> invokers, URL url, Invocation invocation) {
         invokers.forEach((routerValue, list) -> {
             TreeNode<T> node = new TreeNode<>(router.getName(), 
router.getKey(), routerValue, list, router.isForce());
             parentNode.addChild(node);
             // Only when we have more routers and the sub-lis is not empty.
             if (i < routers.size() && CollectionUtils.isNotEmpty(list)) {
                 Router nextRouter = routers.get(i);
-                routeeee(nextRouter, i + 1, node, nextRouter.preRoute(list, 
url, invocation), url, invocation);
+                doRoute(nextRouter, i + 1, node, nextRouter.preRoute(list, 
url, invocation), url, invocation);
             }
         });
     }
 
+    /**
+     *
+     * @param url
+     * @param invocation
+     * @return
+     */
     public List<Invoker<T>> route(URL url, Invocation invocation) {
         List<Invoker<T>> finalInvokers = 
treeCache.getInvokers(treeCache.getTree(), url, invocation);
         for (Router router : routers) {
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
index 2cee248..1f51999 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
@@ -87,13 +87,7 @@ public abstract class AbstractDirectory<T> implements 
Directory<T> {
     protected void addRouters(List<Router> routers) {
         // copy list
         routers = routers == null ? new ArrayList<>() : new 
ArrayList<>(routers);
-        routers.forEach(this::addRouter);
-    }
-
-    protected void addRouter(Router router) {
-        routerChain.addRouter(router);
-        // FIXME append mock invoker selector
-//        routerChain.add(new MockInvokersSelector());
+        routerChain.setGeneratedRouters(routers);
     }
 
     public URL getConsumerUrl() {
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
index bb76236..dc8b63b 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/AbstractRouter.java
@@ -48,19 +48,14 @@ public abstract class AbstractRouter implements Router {
     }
 
     @Override
-    public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, 
Invocation invocation) throws RpcException {
-        return invokers;
-    }
-
-    @Override
     public <T> Map<String, List<Invoker<T>>> preRoute(List<Invoker<T>> 
invokers, URL url, Invocation invocation) throws RpcException {
         Map<String, List<Invoker<T>>> map = new HashMap<>();
 
-        if (CollectionUtils.isEmpty(invokers) || !isEnabled()) {
+        if (CollectionUtils.isEmpty(invokers)) {
             return map;
         }
 
-        if (isRuntime()) {
+        if (isRuntime() || !isEnabled()) {
             map.put(TreeNode.FAILOVER_KEY, invokers);
         } else {
             map.put(TreeNode.FAILOVER_KEY, route(invokers, url, invocation));
@@ -102,4 +97,9 @@ public abstract class AbstractRouter implements Router {
     public void setPriority(int priority) {
         this.priority = priority;
     }
+
+    @Override
+    public int compareTo(Router o) {
+        return (this.getPriority() >= o.getPriority()) ? 1 : -1;
+    }
 }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/InvokerTreeCache.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/InvokerTreeCache.java
index fbad2b4..812632a 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/InvokerTreeCache.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/InvokerTreeCache.java
@@ -33,12 +33,12 @@ public class InvokerTreeCache<T> {
 
     private TreeNode<T> tree;
 
-    public TreeNode buildTree() {
-        tree = new TreeNode<>();
-        tree.setRouterName("ROOT_ROUTER");
-        tree.setConditionValue("root");
-        tree.setConditionKey("root");
-        return tree;
+    public TreeNode<T> buildRootNode() {
+        TreeNode<T> rootNode = new TreeNode<>();
+        rootNode.setRouterName("ROOT_ROUTER");
+        rootNode.setConditionValue("root");
+        rootNode.setConditionKey("root");
+        return rootNode;
     }
 
     public List<Invoker<T>> getInvokers(TreeNode<T> node, URL url, Invocation 
invocation) {
@@ -116,7 +116,11 @@ public class InvokerTreeCache<T> {
     }
 
 
-    public TreeNode getTree() {
+    public void refreshTree(TreeNode<T> node) {
+        this.tree = node;
+    }
+
+    public TreeNode<T> getTree() {
         return tree;
     }
 
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
index f1fc6c7..57f6197 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionRouter.java
@@ -44,10 +44,9 @@ import java.util.regex.Pattern;
  *
  */
 public class ConditionRouter extends AbstractRouter implements 
Comparable<Router> {
-
+    public static final String NAME = "CONDITION_ROUTER";
     private static final Logger logger = 
LoggerFactory.getLogger(ConditionRouter.class);
     protected static Pattern ROUTE_PATTERN = 
Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)");
-    protected URL url;
     protected Map<String, MatchPair> whenCondition;
     protected Map<String, MatchPair> thenCondition;
 
@@ -182,6 +181,11 @@ public class ConditionRouter extends AbstractRouter 
implements Comparable<Router
     }
 
     @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
     public boolean isRuntime() {
         // We always return true for previously defined Router, that is, old 
Router doesn't support cache anymore.
 //        return true;
@@ -189,17 +193,13 @@ public class ConditionRouter extends AbstractRouter 
implements Comparable<Router
     }
 
     @Override
-    public URL getUrl() {
-        return url;
+    public boolean isEnabled() {
+        return url.getParameter(Constants.ENABLED_KEY, false);
     }
 
     @Override
-    public int compareTo(Router o) {
-        if (o == null || o.getClass() != ConditionRouter.class) {
-            return 1;
-        }
-        ConditionRouter c = (ConditionRouter) o;
-        return this.priority > c.priority ? 1 : -1;
+    public URL getUrl() {
+        return url;
     }
 
     boolean matchWhen(URL url, Invocation invocation) {
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
index 3395baa..90e59d9 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouter.java
@@ -46,6 +46,7 @@ import java.util.Map;
  */
 public class ConfigConditionRouter extends AbstractRouter implements 
ConfigurationListener {
     public static final String NAME = "CONFIG_CONDITION_OUTER";
+    public static final int DEFAULT_PRIORITY = 200;
     private static final Logger logger = 
LoggerFactory.getLogger(ConfigConditionRouter.class);
     private DynamicConfiguration configuration;
     private ConditionRouterRule routerRule;
@@ -55,24 +56,32 @@ public class ConfigConditionRouter extends AbstractRouter 
implements Configurati
 
     public ConfigConditionRouter(DynamicConfiguration configuration, URL url) {
         this.configuration = configuration;
-        this.priority = -2;
         this.force = false;
         this.url = url;
+        String app = this.url.getParameter(Constants.APPLICATION_KEY);
+        String serviceKey = this.url.getServiceKey();
         try {
-            String app = this.url.getParameter(Constants.APPLICATION_KEY);
-            String serviceKey = this.url.getServiceKey();
             String rawRule = this.configuration.getConfig(serviceKey + 
Constants.ROUTERS_SUFFIX, "dubbo", this);
             String appRawRule = this.configuration.getConfig(app + 
Constants.ROUTERS_SUFFIX, "dubbo", this);
             if (!StringUtils.isEmpty(rawRule)) {
-                routerRule = ConditionRuleParser.parse(rawRule);
-                generateConditions();
+                try {
+                    routerRule = ConditionRuleParser.parse(rawRule);
+                    generateConditions();
+                } catch (Exception e) {
+                    logger.error("Failed to parse the raw condition rule and 
it will not take effect, please check if the condition rule matches with the 
template, the raw rule is: \n" + rawRule, e);
+                }
             }
             if (!StringUtils.isEmpty(appRawRule)) {
-                appRouterRule = ConditionRuleParser.parse(appRawRule);
-                generateAppConditions();
+                try {
+                    appRouterRule = ConditionRuleParser.parse(appRawRule);
+                    generateAppConditions();
+                } catch (Exception e) {
+                    logger.error("Failed to parse the raw condition rule and 
it will not take effect, please check if the condition rule matches with the 
template, the raw rule is: \n" + appRawRule, e);
+                }
             }
+
         } catch (Exception e) {
-            throw new IllegalStateException("Failed to init the condition 
router.", e);
+            throw new IllegalStateException("Failed to init the condition 
router for service " + serviceKey + ", application " + app, e);
         }
     }
 
@@ -152,6 +161,16 @@ public class ConfigConditionRouter extends AbstractRouter 
implements Configurati
     }
 
     @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    public int getPriority() {
+        return DEFAULT_PRIORITY;
+    }
+
+    @Override
     public boolean isRuntime() {
         return isRuleRuntime() || isAppRuleRuntime();
     }
@@ -175,16 +194,6 @@ public class ConfigConditionRouter extends AbstractRouter 
implements Configurati
                 || (appRouterRule != null && appRouterRule.isForce());
     }
 
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    @Override
-    public int compareTo(Router o) {
-        return 0;
-    }
-
     private boolean isAppRuleEnabled() {
         return appRouterRule != null && appRouterRule.isValid() && 
appRouterRule.isEnabled();
     }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouterFactory.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouterFactory.java
index a81333d..c69cb94 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouterFactory.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ConfigConditionRouterFactory.java
@@ -25,7 +25,7 @@ import org.apache.dubbo.rpc.cluster.RouterFactory;
 /**
  *
  */
-@Activate
+@Activate(order = 200)
 public class ConfigConditionRouterFactory implements RouterFactory {
     @Override
     public Router getRouter(URL url) {
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 5dc954a..66f9ccb 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
@@ -34,6 +34,8 @@ import java.util.List;
  */
 public class MockInvokersSelector extends AbstractRouter {
 
+    public static final String NAME = "MOCK_ROUTER";
+
     @Override
     public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers,
                                       URL url, final Invocation invocation) 
throws RpcException {
@@ -89,6 +91,17 @@ public class MockInvokersSelector extends AbstractRouter {
     }
 
     @Override
+    public String getName() {
+        return NAME;
+    }
+
+    /**
+     * Always stay on the top of the list
+     *
+     * @param o
+     * @return
+     */
+    @Override
     public int compareTo(Router o) {
         return 1;
     }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/ScriptRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/ScriptRouter.java
index 514ebda..7f1ceca 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/ScriptRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/ScriptRouter.java
@@ -24,7 +24,6 @@ import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.cluster.Router;
 import org.apache.dubbo.rpc.cluster.router.AbstractRouter;
 
 import javax.script.Bindings;
@@ -44,7 +43,7 @@ import java.util.concurrent.ConcurrentHashMap;
  *
  */
 public class ScriptRouter extends AbstractRouter {
-
+    public static final String NAME = "SCRIPT_ROUTER";
     private static final Logger logger = 
LoggerFactory.getLogger(ScriptRouter.class);
 
     private static final Map<String, ScriptEngine> engines = new 
ConcurrentHashMap<String, ScriptEngine>();
@@ -55,8 +54,6 @@ public class ScriptRouter extends AbstractRouter {
 
     private final String rule;
 
-    private final URL url;
-
     public ScriptRouter(URL url) {
         this.url = url;
         String type = url.getParameter(Constants.TYPE_KEY);
@@ -116,6 +113,11 @@ public class ScriptRouter extends AbstractRouter {
     }
 
     @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
     public boolean isRuntime() {
         return this.url.getParameter(Constants.RUNTIME_KEY, false);
     }
@@ -126,12 +128,7 @@ public class ScriptRouter extends AbstractRouter {
     }
 
     @Override
-    public int compareTo(Router o) {
-        if (o == null || o.getClass() != ScriptRouter.class) {
-            return 1;
-        }
-        ScriptRouter c = (ScriptRouter) o;
-        return this.priority == c.priority ? rule.compareTo(c.rule) : 
(this.priority > c.priority ? 1 : -1);
+    public boolean isEnabled() {
+        return url.getParameter(Constants.ENABLED_KEY, false);
     }
-
 }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
index 88b6dad..6fe4890 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
@@ -49,14 +49,13 @@ import java.util.stream.Collectors;
  */
 public class TagRouter extends AbstractRouter implements Comparable<Router>, 
ConfigurationListener {
     public static final String NAME = "TAG_ROUTER";
+    public static final int DEFAULT_PRIORITY = 100;
     private static final Logger logger = 
LoggerFactory.getLogger(TagRouter.class);
     private static final String TAGROUTERRULES_DATAID = ".tagrouters"; // acts
     private DynamicConfiguration configuration;
     private TagRouterRule tagRouterRule;
     private String application;
 
-    protected int priority = -1; // FIXME A fixed value considering other 
routers in the chain.
-
     public TagRouter(URL url) {
         
this(ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getAdaptiveExtension().getDynamicConfiguration(url),
 url);
     }
@@ -245,6 +244,11 @@ public class TagRouter extends AbstractRouter implements 
Comparable<Router>, Con
     }
 
     @Override
+    public int getPriority() {
+        return DEFAULT_PRIORITY;
+    }
+
+    @Override
     public boolean isRuntime() {
         return tagRouterRule != null && tagRouterRule.isRuntime();
 //        return false;
@@ -281,9 +285,4 @@ public class TagRouter extends AbstractRouter implements 
Comparable<Router>, Con
     public void setApplication(String app) {
         this.application = app;
     }
-
-    @Override
-    public int compareTo(Router o) {
-        return 0;
-    }
 }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
index bb52ef3..2a7cf38 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java
@@ -25,7 +25,7 @@ import org.apache.dubbo.rpc.cluster.RouterFactory;
 /**
  *
  */
-@Activate
+@Activate(order = 100)
 public class TagRouterFactory implements RouterFactory {
 
     public static final String NAME = "tag";
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 1c4cbc5..4cd3a04 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -378,6 +378,7 @@
                 <groupId>commons-configuration</groupId>
                 <artifactId>commons-configuration</artifactId>
                 <version>${commons_configuration_version}</version>
+                <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.apache.commons</groupId>
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
index 5ea0ddf..09e82fd 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
@@ -304,6 +304,7 @@ public class RegistryDirectory<T> extends 
AbstractDirectory<T> implements Notify
             this.forbidden = true; // Forbid to access
             this.methodInvokerMap = null; // Set the method invoker map to null
             destroyAllInvokers(); // Close all invokers
+            routerChain.notifyFullInvokers(this.methodInvokerMap, 
getConsumerUrl());
         } else {
             this.forbidden = false; // Allow to access
             Map<String, Invoker<T>> oldUrlInvokerMap = this.urlInvokerMap; // 
local reference
@@ -325,7 +326,7 @@ public class RegistryDirectory<T> extends 
AbstractDirectory<T> implements Notify
                 return;
             }
             // pre-route and build cache, notice that route cache should build 
on original Invoker list.
-            // toMergeMethodInvokerMap() will wrap some invokers having 
different groups, those wrapped invokers should be routed.
+            // toMergeMethodInvokerMap() will wrap some invokers having 
different groups, those wrapped invokers not should be routed.
             routerChain.notifyFullInvokers(newMethodInvokerMap, 
getConsumerUrl());
             this.methodInvokerMap = multiGroup ? 
toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap;
             this.urlInvokerMap = newUrlInvokerMap;
@@ -392,6 +393,7 @@ public class RegistryDirectory<T> extends 
AbstractDirectory<T> implements Notify
                 try {
                     Router router = routerFactory.getRouter(url);
                     router.setRouterChain(routerChain);
+//                    routerChain.addRouter(router);
                     if (!routers.contains(router))
                         routers.add(router);
                 } catch (Throwable t) {

Reply via email to