in pkg/adapter/springcloud/cloud.go [284:336]
func (a *CloudAdapter) fetchCompareAndSet() {
instances, err := a.fetchServiceByConfig()
if err != nil {
logger.Warnf("fetchCompareAndSet all service error ", err.Error())
return
}
_ = a.watch()
// manage cluster and route
cm := server.GetClusterManager()
rm := server.GetRouterManager()
a.mutex.Lock()
defer a.mutex.Unlock()
oldStore, err := cm.CloneStore()
if err != nil {
logger.Warnf("fetchCompareAndSet clone store error ", err.Error())
}
newStore := cm.NewStore(oldStore.Version)
for _, instance := range instances {
endpoint := instance.ToEndpoint()
// endpoint name should equal with cluster name
newStore.SetEndpoint(endpoint.Name, endpoint)
}
// maximize reduction the interval of down state
// first remove the router for removed cluster
for _, c := range oldStore.Config {
if !newStore.HasCluster(c.Name) {
rm.DeleteRouter(&model.Router{ID: c.Name})
}
}
// second set cluster
ret := cm.CompareAndSetStore(newStore)
if !ret {
// fast fail the delete route at first phase shouldn't recover
return
}
// third add new router
for _, c := range newStore.Config {
if !oldStore.HasCluster(c.Name) {
match := model.NewRouterMatchPrefix(c.Name)
route := model.RouteAction{Cluster: c.Name}
added := &model.Router{ID: c.Name, Match: match, Route: route}
rm.AddRouter(added)
}
}
}