Aetherance commented on code in PR #3252:
URL: https://github.com/apache/dubbo-go/pull/3252#discussion_r2976093355


##########
cluster/router/chain/chain.go:
##########
@@ -106,6 +107,85 @@ func (c *RouterChain) copyRouters() 
[]router.PriorityRouter {
        return ret
 }
 
+// getApplicationName gets the application name from URL with fallback to 
SubURL
+func getApplicationName(url *common.URL) string {
+       appName := url.GetParam(constant.ApplicationKey, "")
+       if appName == "" && url.SubURL != nil {
+               appName = url.SubURL.GetParam(constant.ApplicationKey, "")
+       }
+       return appName
+}
+
+// isRouterMatch checks if router configuration matches the current 
service/application
+func isRouterMatch(routerCfg *global.RouterConfig, url *common.URL, appName 
string) bool {
+       switch routerCfg.Scope {
+       case constant.RouterScopeService:
+               if url.SubURL != nil {
+                       return routerCfg.Key == url.SubURL.ServiceKey()
+               }
+               return routerCfg.Key == url.ServiceKey()
+       case constant.RouterScopeApplication:
+               return routerCfg.Key == appName
+       default:
+               logger.Warnf("unknown router scope: %s", routerCfg.Scope)
+               return false
+       }
+}
+
+// injectStaticRouters injects static router configurations into the router 
chain.
+// Called after all routers are created to ensure they exist.
+// The injected static configs act as bootstrap state only during 
initialization. For the shared
+// static and dynamic lifecycle semantics, see router.StaticConfigSetter.
+func (c *RouterChain) injectStaticRouters(url *common.URL) {
+       staticRoutersAttrAny, ok := url.GetAttribute(constant.RoutersConfigKey)
+       if !ok && url.SubURL != nil {
+               staticRoutersAttrAny, ok = 
url.SubURL.GetAttribute(constant.RoutersConfigKey)
+       }
+       if !ok {
+               return
+       }
+       staticRoutersAttr, ok := staticRoutersAttrAny.([]*global.RouterConfig)
+       if !ok {
+               logger.Warnf("failed to type assert routers config: expected 
[]*global.RouterConfig, got %T", staticRoutersAttrAny)
+               return
+       }
+       if len(staticRoutersAttr) == 0 {
+               return
+       }
+
+       applicationName := getApplicationName(url)
+
+       for _, routerCfg := range staticRoutersAttr {
+               if routerCfg == nil {
+                       continue
+               }
+               if routerCfg.Enabled != nil && !*routerCfg.Enabled {
+                       continue
+               }
+               if routerCfg.Valid != nil && !*routerCfg.Valid {
+                       continue
+               }
+               if !isRouterMatch(routerCfg, url, applicationName) {
+                       continue
+               }
+               c.injectRouterConfig(routerCfg)
+       }
+}
+
+// injectRouterConfig injects router configuration into routers that implement 
StaticConfigSetter.
+// Each router decides whether the config applies to it and no-ops if not.
+func (c *RouterChain) injectRouterConfig(routerCfg *global.RouterConfig) {
+       routerCfgCopy := routerCfg.Clone()
+
+       c.mutex.RLock()
+       defer c.mutex.RUnlock()
+       for _, r := range c.routers {
+               if setter, ok := r.(router.StaticConfigSetter); ok {
+                       setter.SetStaticConfig(routerCfgCopy.Clone())

Review Comment:
   外层 clone 的作用是为本次注入建立一份入口快照,避免原始 cfg 如果在循环期间被外部改动,导致不同 router 看到不同版本的配置.   内层 
clone 的作用是隔离各 router 的 SetStaticConfig ,避免某个 router 因实现不当修改传入配置后影响其他 router。
   
   当前代码中暂时不存在循环期间并发修改原始 cfg 的场景,因此内层 clone 是必要的,如果考虑性能因素,外层 clone 当前可以去掉,但是内层 
clone 应该保留。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to