Skip to content
Snippets Groups Projects
Commit c1678424 authored by Ian Luo's avatar Ian Luo
Browse files

avoid of copying and comparing invokers as much as possible

parent fd183d84
No related branches found
No related tags found
No related merge requests found
...@@ -167,21 +167,35 @@ func (c *RouterChain) loadCache() *InvokerCache { ...@@ -167,21 +167,35 @@ func (c *RouterChain) loadCache() *InvokerCache {
return v.(*InvokerCache) return v.(*InvokerCache)
} }
// copyInvokerIfNecessary compares chain's invokers copy and cache's invokers copy, to avoid copy as much as possible
func (c *RouterChain) copyInvokerIfNecessary(cache *InvokerCache) []protocol.Invoker {
var invokers []protocol.Invoker
if cache != nil {
invokers = cache.invokers
}
c.mutex.RLock()
defer c.mutex.RUnlock()
if isInvokersChanged(invokers, c.invokers) {
invokers = c.copyInvokers()
}
return invokers
}
// buildCache builds address cache with the new invokers for all poolable routers. // buildCache builds address cache with the new invokers for all poolable routers.
func (c *RouterChain) buildCache() { func (c *RouterChain) buildCache() {
invokers := c.copyInvokers() origin := c.loadCache()
if invokers == nil || len(c.invokers) == 0 { invokers := c.copyInvokerIfNecessary(origin)
if invokers == nil || len(invokers) == 0 {
return return
} }
cache := BuildCache(invokers)
origin := c.loadCache()
var ( var (
mutex sync.Mutex mutex sync.Mutex
wg sync.WaitGroup wg sync.WaitGroup
) )
cache := BuildCache(invokers)
for _, r := range c.copyRouters() { for _, r := range c.copyRouters() {
if p, ok := r.(router.Poolable); ok { if p, ok := r.(router.Poolable); ok {
wg.Add(1) wg.Add(1)
...@@ -246,7 +260,7 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) { ...@@ -246,7 +260,7 @@ func NewRouterChain(url *common.URL) (*RouterChain, error) {
// rule doesn't change), and the address list doesn't change, then the existing data will be re-used. // rule doesn't change), and the address list doesn't change, then the existing data will be re-used.
func poolRouter(p router.Poolable, origin *InvokerCache, invokers []protocol.Invoker) (router.AddrPool, router.AddrMetadata) { func poolRouter(p router.Poolable, origin *InvokerCache, invokers []protocol.Invoker) (router.AddrPool, router.AddrMetadata) {
name := p.Name() name := p.Name()
if isCacheMiss(origin, name) || p.ShouldPool() || isInvokersChanged(origin.invokers, invokers) { if isCacheMiss(origin, name) || p.ShouldPool() || &(origin.invokers) != &invokers {
logger.Debugf("build address cache for router %q", name) logger.Debugf("build address cache for router %q", name)
return p.Pool(invokers) return p.Pool(invokers)
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment