in pkg/providers/apisix/apisix_route.go [154:222]
func (c *apisixRouteController) syncRelationship(ev *types.Event, routeKey string, ar kube.ApisixRoute) {
obj := ev.Object.(kube.ApisixRouteEvent)
var (
oldBackends []string
newBackends []string
oldUpstreams []string
newUpstreams []string
)
switch obj.GroupVersion {
case config.ApisixV2:
var (
old *v2.ApisixRoute
newObj *v2.ApisixRoute
)
if ev.Type == types.EventUpdate {
old = obj.OldObject.V2()
} else if ev.Type == types.EventDelete {
old = ev.Tombstone.(kube.ApisixRoute).V2()
}
if ev.Type != types.EventDelete {
newObj = ar.V2()
}
// calculate diff, so we don't need to care about the event order
if old != nil {
for _, rule := range old.Spec.HTTP {
for _, backend := range rule.Backends {
oldBackends = append(oldBackends, old.Namespace+"/"+backend.ServiceName)
}
for _, upstream := range rule.Upstreams {
oldUpstreams = append(oldUpstreams, old.Namespace+"/"+upstream.Name)
}
}
}
if newObj != nil {
for _, rule := range newObj.Spec.HTTP {
for _, backend := range rule.Backends {
newBackends = append(newBackends, newObj.Namespace+"/"+backend.ServiceName)
}
for _, upstream := range rule.Upstreams {
newUpstreams = append(newUpstreams, newObj.Namespace+"/"+upstream.Name)
}
}
}
default:
log.Errorw("unknown ApisixRoute version",
zap.String("version", obj.GroupVersion),
zap.String("key", obj.Key),
)
}
// NOTE:
// This implementation MAY cause potential problem due to unstable event order
// The last event processed MAY not be the logical last event, so it may override the logical previous event
// We have a periodic full-sync, which reduce this problem, but it doesn't solve it completely.
toDelete := utils.Difference(oldBackends, newBackends)
toAdd := utils.Difference(newBackends, oldBackends)
c.syncServiceRelationChanges(routeKey, toAdd, toDelete)
toDelete = utils.Difference(oldUpstreams, newUpstreams)
toAdd = utils.Difference(newUpstreams, oldUpstreams)
c.syncApisixUpstreamRelationChanges(routeKey, toAdd, toDelete)
}