// UpdateRSWithRetries updates a RS with given applyUpdate function. Note that RS not found error is ignored. // The returned bool value can be used to tell if the RS is actually updated. func UpdateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rs *extensions.ReplicaSet, applyUpdate updateRSFunc) (*extensions.ReplicaSet, bool, error) { var err error var rsUpdated bool oldRs := rs if err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { rs, err = rsClient.Get(oldRs.Name) if err != nil { return false, err } // Apply the update, then attempt to push it to the apiserver. if err = applyUpdate(rs); err != nil { return false, err } if rs, err = rsClient.Update(rs); err == nil { // Update successful. return true, nil } // TODO: don't retry on perm-failed errors and handle them gracefully // Update could have failed due to conflict error. Try again. return false, nil }); err == nil { // When there's no error, we've updated this RS. rsUpdated = true } // Handle returned error from wait poll if err == wait.ErrWaitTimeout { err = fmt.Errorf("timed out trying to update RS: %+v", oldRs) } // Ignore the RS not found error, but the RS isn't updated. if errors.IsNotFound(err) { glog.V(4).Infof("%s %s/%s is not found, skip updating it.", oldRs.Kind, oldRs.Namespace, oldRs.Name) err = nil } // Ignore the precondition violated error, but the RS isn't updated. if err == errorsutil.ErrPreconditionViolated { glog.V(4).Infof("%s %s/%s precondition doesn't hold, skip updating it.", oldRs.Kind, oldRs.Namespace, oldRs.Name) err = nil } // If the error is non-nil the returned RS cannot be trusted; if rsUpdated is false, the contoller isn't updated; // if the error is nil and rsUpdated is true, the returned RS contains the applied update. return rs, rsUpdated, err }
func updateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rs *extensions.ReplicaSet, applyUpdate updateRSFunc) (*extensions.ReplicaSet, error) { var err error oldRs := rs err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { rs, err = rsClient.Get(oldRs.Name) if err != nil { return false, err } // Apply the update, then attempt to push it to the apiserver. applyUpdate(rs) if rs, err = rsClient.Update(rs); err == nil { // Update successful. return true, nil } // Update could have failed due to conflict error. Try again. return false, nil }) // If the error is non-nil the returned controller cannot be trusted, if it is nil, the returned // controller contains the applied update. return rs, err }
func updateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rs *extensions.ReplicaSet, applyUpdate updateRSFunc) (*extensions.ReplicaSet, error) { var err error oldRs := rs err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { // Apply the update, then attempt to push it to the apiserver. applyUpdate(rs) if rs, err = rsClient.Update(rs); err == nil { // rs contains the latest controller post update return true, nil } // Update the controller with the latest resource version, if the update failed we // can't trust rs so use oldRs.Name. if rs, err = rsClient.Get(oldRs.Name); err != nil { // The Get failed: Value in rs cannot be trusted. rs = oldRs } // The Get passed: rs contains the latest controller, expect a poll for the update. return false, nil }) // If the error is non-nil the returned controller cannot be trusted, if it is nil, the returned // controller contains the applied update. return rs, err }