// admitRoute returns true if the route has already been accepted to this router, or // updates the route to contain an accepted condition. Returns an error if the route could // not be admitted. func (a *StatusAdmitter) admitRoute(oc client.RoutesNamespacer, route *routeapi.Route, name string) (bool, error) { ingress, updated := findOrCreateIngress(route, name) if !updated { for i := range ingress.Conditions { cond := &ingress.Conditions[i] if cond.Type == routeapi.RouteAdmitted && cond.Status == kapi.ConditionTrue { glog.V(4).Infof("admit: route already admitted") return true, nil } } } if a.hasIngressBeenTouched(route, ingressConditionTouched(ingress)) { glog.V(4).Infof("admit: observed a route update from someone else: route %s/%s has been updated to an inconsistent value, doing nothing", route.Namespace, route.Name) return true, nil } setIngressCondition(ingress, routeapi.RouteIngressCondition{ Type: routeapi.RouteAdmitted, Status: kapi.ConditionTrue, }) glog.V(4).Infof("admit: admitting route by updating status: %s (%t): %s", route.Name, updated, route.Spec.Host) _, err := oc.Routes(route.Namespace).UpdateStatus(route) a.recordIngressTouch(route, ingress.Conditions[0].LastTransitionTime, err) return err == nil, err }
// admitRoute returns true if the route has already been accepted to this router, or // updates the route to contain an accepted condition. Returns an error if the route could // not be admitted due to a failure, or false if the route can't be admitted at this time. func (a *StatusAdmitter) admitRoute(oc client.RoutesNamespacer, route *routeapi.Route, name string) (bool, error) { ingress, updated := findOrCreateIngress(route, name) // keep lastTouch around lastTouch := ingressConditionTouched(ingress) if !updated { for i := range ingress.Conditions { cond := &ingress.Conditions[i] if cond.Type == routeapi.RouteAdmitted && cond.Status == kapi.ConditionTrue { // reduce extra round trips during the contention period by remembering this // time, so we don't react later if _, ok := a.expected.Get(route.UID); !ok { a.expected.Add(route.UID, lastTouch.Time) } glog.V(4).Infof("admit: route already admitted") return true, nil } } } // this works by keeping a cache of what time we last touched the route. // If the recorded last-touch time matches ours, then we were the ones to do the // last update, and can continue forth. Additionally, if we have no entry in our // cache, we continue forward anyways. Since replicas from a new deployment will // have no entry, they will update the last-touch time, and therefore take "ownership" // of updating the route. In the case of a new route being created during a rolling update, // there will be a race to determine whether the old or new deployment gets to determine, // but this will be corrected on the next event after contentionInterval time. if a.hasIngressBeenTouched(route, lastTouch) { glog.V(4).Infof("admit: observed a route update from someone else: route %s/%s has been updated to an inconsistent value, doing nothing", route.Namespace, route.Name) return true, nil } setIngressCondition(ingress, routeapi.RouteIngressCondition{ Type: routeapi.RouteAdmitted, Status: kapi.ConditionTrue, }) glog.V(4).Infof("admit: admitting route by updating status: %s (%t): %s", route.Name, updated, route.Spec.Host) _, err := oc.Routes(route.Namespace).UpdateStatus(route) return a.recordIngressTouch(route, ingress.Conditions[0].LastTransitionTime, lastTouch, err) }