in registry/directory/directory.go [201:264]
func (dir *RegistryDirectory) refreshAllInvokers(events []*registry.ServiceEvent, callback func()) {
var (
oldInvokers []protocol.Invoker
addEvents []*registry.ServiceEvent
)
dir.overrideUrl(dir.GetDirectoryUrl())
referenceUrl := dir.GetDirectoryUrl().SubURL
// loop the events to check the Action should be EventTypeUpdate.
for _, event := range events {
if event.Action != remoting.EventTypeUpdate && event.Action != remoting.EventTypeAdd {
panic("Your implements of register center is wrong, " +
"please check the Action of ServiceEvent should be EventTypeUpdate")
}
// Originally it will Merge URL many times, now we just execute once.
// MergeURL is executed once and put the result into Event. After this, the key will get from Event.Key().
newUrl := dir.convertUrl(event)
newUrl = newUrl.MergeURL(referenceUrl)
dir.overrideUrl(newUrl)
event.Update(newUrl)
}
// After notify all addresses, do some callback.
defer callback()
func() {
// this lock is work at batch update of InvokeCache
dir.registerLock.Lock()
defer dir.registerLock.Unlock()
// get need clear invokers from original invoker list
dir.cacheInvokersMap.Range(func(k, v any) bool {
if !dir.eventMatched(k.(string), events) {
// delete unused invoker from cache
if invoker := dir.uncacheInvokerWithKey(k.(string)); invoker != nil {
oldInvokers = append(oldInvokers, invoker)
}
}
return true
})
// get need add invokers from events
for _, event := range events {
// Get the key from Event.Key()
if _, ok := dir.cacheInvokersMap.Load(event.Key()); !ok {
addEvents = append(addEvents, event)
}
}
// loop the serviceEvents
for _, event := range addEvents {
logger.Debugf("[Registry Directory] registry changed, result{%s}", event)
if event != nil && event.Service != nil {
logger.Infof("[Registry Directory] selector add service url{%s}", event.Service.String())
}
if event != nil && event.Service != nil && constant.RouterProtocol == event.Service.Protocol {
dir.configRouters()
}
if oldInvoker, _ := dir.doCacheInvoker(event.Service, event); oldInvoker != nil {
oldInvokers = append(oldInvokers, oldInvoker)
}
}
}()
dir.setNewInvokers()
// destroy unused invokers
for _, invoker := range oldInvokers {
go invoker.Destroy()
}
}