diff --git a/cluster/directory/base_directory.go b/cluster/directory/base_directory.go index 5ea9858214f16e53e72934a59853a04a0207fd6e..dc3902291c4017188506b1b8a5f2d3bcf454a609 100644 --- a/cluster/directory/base_directory.go +++ b/cluster/directory/base_directory.go @@ -41,7 +41,6 @@ type BaseDirectory struct { url *common.URL destroyed *atomic.Bool mutex sync.Mutex - once sync.Once routerChain router.Chain } @@ -87,8 +86,6 @@ func (dir *BaseDirectory) SetRouters(routers []router.Router) { } } - dir.mutex.Lock() - defer dir.mutex.Unlock() dir.routerChain.AddRouters(routers) } diff --git a/cluster/directory/static_directory.go b/cluster/directory/static_directory.go index b7757ea91e7156fceb47cf924732e22f576a7d1b..abe03db90acad0002be0671f784bb81e2931d42d 100644 --- a/cluster/directory/static_directory.go +++ b/cluster/directory/static_directory.go @@ -54,7 +54,9 @@ func (dir *staticDirectory) IsAvailable() bool { } func (dir *staticDirectory) List(invocation protocol.Invocation) []protocol.Invoker { - invokers := dir.invokers + l := len(dir.invokers) + invokers := make([]protocol.Invoker, l, l) + copy(invokers, dir.invokers) routerChain := dir.RouterChain() if routerChain == nil { diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index 4ca596886f920e05b295f44ec95b86321592c8e4..d85fb3d0e246ae1ea24785e58feafd7b5beb3cc7 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -19,6 +19,7 @@ package chain import ( "sort" + "sync" ) import ( @@ -42,11 +43,19 @@ type RouterChain struct { // Fixed router instances: ConfigConditionRouter, TagRouter, e.g., the rule for each instance may change but the // instance will never delete or recreate. builtinRouters []router.Router + + mutex sync.RWMutex } func (c RouterChain) Route(invoker []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker { finalInvokers := invoker - for _, r := range c.routers { + l := len(c.routers) + rs := make([]router.Router, l, l) + c.mutex.RLock() + copy(rs, c.routers) + c.mutex.RUnlock() + + for _, r := range rs { finalInvokers = r.Route(invoker, url, invocation) } return finalInvokers @@ -56,6 +65,8 @@ func (c RouterChain) AddRouters(routers []router.Router) { newRouters = append(newRouters, c.builtinRouters...) newRouters = append(newRouters, routers...) sortRouter(newRouters) + c.mutex.Lock() + defer c.mutex.Unlock() c.routers = newRouters }