1818
1919import org .apache .dubbo .common .URL ;
2020import org .apache .dubbo .common .extension .ExtensionLoader ;
21- import org .apache .dubbo .common .utils .CollectionUtils ;
2221import org .apache .dubbo .rpc .Invocation ;
2322import org .apache .dubbo .rpc .Invoker ;
2423
3332public class RouterChain <T > {
3433
3534 // full list of addresses from registry, classified by method name.
36- private List <Invoker <T >> fullInvokers ;
35+ private List <Invoker <T >> invokers = Collections . emptyList () ;
3736 private URL url ;
3837
3938 // containing all routers, reconstruct every time 'route://' urls change.
40- private List <Router > routers = new CopyOnWriteArrayList <>();
41- // Fixed router instances: ConfigConditionRouter, TagRouter, e.g., the rule for each instance may change but the instance will never delete or recreate.
42- private List <Router > residentRouters ;
39+ private volatile List <Router > routers = Collections .emptyList ();
4340
44- public static <T > RouterChain <T > buildChain (URL url ) {
45- RouterChain <T > routerChain = new RouterChain <>(url );
46- List <RouterFactory > extensionFactories = ExtensionLoader .getExtensionLoader (RouterFactory .class ).getActivateExtension (url , (String []) null );
47- List <Router > routers = extensionFactories .stream ()
48- .map (factory -> {
49- Router router = factory .getRouter (url );
50- router .addRouterChain (routerChain );
51- return router ;
52- }).collect (Collectors .toList ());
53- routerChain .setResidentRouters (routers );
54- return routerChain ;
55- }
41+ // Fixed router instances: ConfigConditionRouter, TagRouter, e.g., the rule for each instance may change but the
42+ // instance will never delete or recreate.
43+ private List <Router > builtinRouters = Collections .emptyList ();
5644
57- protected RouterChain ( List < Router > routers ) {
58- this . routers . addAll ( routers );
45+ public static < T > RouterChain < T > buildChain ( URL url ) {
46+ return new RouterChain <>( url );
5947 }
6048
61- protected RouterChain (URL url ) {
49+ private RouterChain (URL url ) {
6250 this .url = url ;
51+
52+ List <RouterFactory > extensionFactories = ExtensionLoader .getExtensionLoader (RouterFactory .class )
53+ .getActivateExtension (url , (String []) null );
54+
55+ List <Router > routers = extensionFactories .stream ()
56+ .map (factory -> factory .getRouter (url ))
57+ .collect (Collectors .toList ());
58+
59+ initWithRouters (routers );
6360 }
6461
6562 /**
6663 * the resident routers must being initialized before address notification.
67- *
68- * @param residentRouters
64+ * FIXME: this method should not be public
6965 */
70- public void setResidentRouters (List <Router > residentRouters ) {
71- this .residentRouters = residentRouters ;
72- this .routers . addAll ( residentRouters );
66+ public void initWithRouters (List <Router > builtinRouters ) {
67+ this .builtinRouters = builtinRouters ;
68+ this .routers = new CopyOnWriteArrayList <>( builtinRouters );
7369 this .sort ();
7470 }
7571
72+ public void addRouter (Router router ) {
73+ this .routers .add (router );
74+ }
75+
7676 /**
7777 * If we use route:// protocol in version before 2.7.0, each URL will generate a Router instance,
7878 * so we should keep the routers up to date, that is, each time router URLs changes, we should update the routers list,
79- * only keep the residentRouters which are available all the time and the latest notified routers which are generated from URLs.
79+ * only keep the builtinRouters which are available all the time and the latest notified routers which are generated from URLs.
8080 *
81- * @param generatedRouters routers from 'router://' rules in 2.6.x or before.
81+ * @param routers routers from 'router://' rules in 2.6.x or before.
8282 */
83- public void setGeneratedRouters (List <Router > generatedRouters ) {
83+ public void addRouters (List <Router > routers ) {
84+ // FIXME will sort cause concurrent problem? since it's kind of a write operation.
8485 List <Router > newRouters = new CopyOnWriteArrayList <>();
85- newRouters .addAll (residentRouters );
86- newRouters .addAll (generatedRouters );
86+ newRouters .addAll (builtinRouters );
87+ newRouters .addAll (routers );
8788 this .routers = newRouters ;
88- // FIXME will sort cause concurrent problem? since it's kind of a write operation.
8989 this .sort ();
90- /* if (fullInvokers != null) {
91- this.preRoute(fullInvokers , url, null);
90+ /* if (invokers != null) {
91+ this.rebuild(invokers , url, null);
9292 }*/
9393 }
9494
95- public void sort () {
95+ private void sort () {
9696 Collections .sort (routers );
9797 }
9898
99- /**
100- * TODO
101- *
102- * Building of router cache can be triggered from within different threads, for example, registry notification and governance notification.
103- * So this operation should be synchronized.
104- * @param invokers
105- * @param url
106- * @param invocation
107- */
108- public void preRoute (List <Invoker <T >> invokers , URL url , Invocation invocation ) {
109- for (Router router : routers ) {
110- router .preRoute (invokers , url , invocation );
111- }
112- }
113-
11499 /**
115100 *
116101 * @param url
117102 * @param invocation
118103 * @return
119104 */
120105 public List <Invoker <T >> route (URL url , Invocation invocation ) {
121- List <Invoker <T >> finalInvokers = fullInvokers ;
106+ List <Invoker <T >> finalInvokers = invokers ;
122107 for (Router router : routers ) {
123108// if (router.isRuntime()) {
124109// finalInvokers = router.route(finalInvokers, url, invocation);
@@ -128,29 +113,14 @@ public List<Invoker<T>> route(URL url, Invocation invocation) {
128113 return finalInvokers ;
129114 }
130115
131- /**
132- * When any of the router's rule changed, notify the router chain to rebuild cache from scratch.
133- */
134- public void notifyRuleChanged () {
135- if (CollectionUtils .isEmpty (this .fullInvokers )) {
136- return ;
137- }
138- preRoute (this .fullInvokers , url , null );
139- }
140-
141116 /**
142117 * Notify router chain of the initial addresses from registry at the first time.
143118 * Notify whenever addresses in registry change.
144- *
145- * @param invokers
146- * @param url
147119 */
148- public void notifyFullInvokers (List <Invoker <T >> invokers , URL url ) {
149- setFullMethodInvokers (invokers );
150- preRoute (invokers , url , null );
151- }
152-
153- public void setFullMethodInvokers (List <Invoker <T >> fullInvokers ) {
154- this .fullInvokers = (fullInvokers == null ? Collections .emptyList () : fullInvokers );
120+ public void setInvokers (List <Invoker <T >> invokers ) {
121+ if (invokers != null ) {
122+ this .invokers = invokers ;
123+ routers .forEach (router -> router .notify (invokers ));
124+ }
155125 }
156126}
0 commit comments