mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Replace PollImmediate with PollUntilContextTimeout (#128147)
* Replace PollImmediate with PollUntilContextTimeout Signed-off-by: Omer Aplatony <omerap12@gmail.com> * Add context to RetryErrorCondition function Signed-off-by: Omer Aplatony <omerap12@gmail.com> * lint: fix error comparison in scale package Signed-off-by: Omer Aplatony <omerap12@gmail.com> * Fix RetryErrorCondition function signature Signed-off-by: Omer Aplatony <omerap12@gmail.com> * revert to if err statement Signed-off-by: Omer Aplatony <omerap12@gmail.com> --------- Signed-off-by: Omer Aplatony <omerap12@gmail.com>
This commit is contained in:
parent
c9024e7ae6
commit
9d816f1587
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package apply
|
package apply
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -387,7 +388,7 @@ func (p *Patcher) deleteAndCreate(original runtime.Object, modified []byte, name
|
|||||||
return modified, nil, err
|
return modified, nil, err
|
||||||
}
|
}
|
||||||
// TODO: use wait
|
// TODO: use wait
|
||||||
if err := wait.PollImmediate(1*time.Second, p.Timeout, func() (bool, error) {
|
if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, p.Timeout, true, func(ctx context.Context) (bool, error) {
|
||||||
if _, err := p.Helper.Get(namespace, name); !apierrors.IsNotFound(err) {
|
if _, err := p.Helper.Get(namespace, name); !apierrors.IsNotFound(err) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package replace
|
package replace
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -358,8 +359,7 @@ func (o *ReplaceOptions) forceReplace() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return wait.PollUntilContextTimeout(context.Background(), 1*time.Second, timeout, true, func(ctx context.Context) (bool, error) {
|
||||||
return wait.PollImmediate(1*time.Second, timeout, func() (bool, error) {
|
|
||||||
if err := info.Get(); !errors.IsNotFound(err) {
|
if err := info.Get(); !errors.IsNotFound(err) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,13 @@ package scale
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
@ -80,14 +81,14 @@ func NewRetryParams(interval, timeout time.Duration) *RetryParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ScaleCondition is a closure around Scale that facilitates retries via util.wait
|
// ScaleCondition is a closure around Scale that facilitates retries via util.wait
|
||||||
func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint, updatedResourceVersion *string, gvr schema.GroupVersionResource, dryRun bool) wait.ConditionFunc {
|
func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint, updatedResourceVersion *string, gvr schema.GroupVersionResource, dryRun bool) wait.ConditionWithContextFunc {
|
||||||
return func() (bool, error) {
|
return func(context.Context) (bool, error) {
|
||||||
rv, err := r.ScaleSimple(namespace, name, precondition, count, gvr, dryRun)
|
rv, err := r.ScaleSimple(namespace, name, precondition, count, gvr, dryRun)
|
||||||
if updatedResourceVersion != nil {
|
if updatedResourceVersion != nil {
|
||||||
*updatedResourceVersion = rv
|
*updatedResourceVersion = rv
|
||||||
}
|
}
|
||||||
// Retry only on update conflicts.
|
// Retry only on update conflicts.
|
||||||
if errors.IsConflict(err) {
|
if apierrors.IsConflict(err) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -171,7 +172,7 @@ func (s *genericScaler) Scale(namespace, resourceName string, newSize uint, prec
|
|||||||
retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
|
retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
|
||||||
}
|
}
|
||||||
cond := ScaleCondition(s, preconditions, namespace, resourceName, newSize, nil, gvr, dryRun)
|
cond := ScaleCondition(s, preconditions, namespace, resourceName, newSize, nil, gvr, dryRun)
|
||||||
if err := wait.PollImmediate(retry.Interval, retry.Timeout, cond); err != nil {
|
if err := wait.PollUntilContextTimeout(context.Background(), retry.Interval, retry.Timeout, true, cond); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if waitForReplicas != nil {
|
if waitForReplicas != nil {
|
||||||
@ -182,9 +183,9 @@ func (s *genericScaler) Scale(namespace, resourceName string, newSize uint, prec
|
|||||||
|
|
||||||
// scaleHasDesiredReplicas returns a condition that will be true if and only if the desired replica
|
// scaleHasDesiredReplicas returns a condition that will be true if and only if the desired replica
|
||||||
// count for a scale (Spec) equals its updated replicas count (Status)
|
// count for a scale (Spec) equals its updated replicas count (Status)
|
||||||
func scaleHasDesiredReplicas(sClient scaleclient.ScalesGetter, gr schema.GroupResource, resourceName string, namespace string, desiredReplicas int32) wait.ConditionFunc {
|
func scaleHasDesiredReplicas(sClient scaleclient.ScalesGetter, gr schema.GroupResource, resourceName string, namespace string, desiredReplicas int32) wait.ConditionWithContextFunc {
|
||||||
return func() (bool, error) {
|
return func(ctx context.Context) (bool, error) {
|
||||||
actualScale, err := sClient.Scales(namespace).Get(context.TODO(), gr, resourceName, metav1.GetOptions{})
|
actualScale, err := sClient.Scales(namespace).Get(ctx, gr, resourceName, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -203,11 +204,9 @@ func WaitForScaleHasDesiredReplicas(sClient scaleclient.ScalesGetter, gr schema.
|
|||||||
if waitForReplicas == nil {
|
if waitForReplicas == nil {
|
||||||
return fmt.Errorf("waitForReplicas parameter cannot be nil")
|
return fmt.Errorf("waitForReplicas parameter cannot be nil")
|
||||||
}
|
}
|
||||||
err := wait.PollImmediate(
|
err := wait.PollUntilContextTimeout(context.Background(), waitForReplicas.Interval, waitForReplicas.Timeout, true, scaleHasDesiredReplicas(sClient, gr, resourceName, namespace, int32(newSize)))
|
||||||
waitForReplicas.Interval,
|
|
||||||
waitForReplicas.Timeout,
|
if errors.Is(err, context.DeadlineExceeded) {
|
||||||
scaleHasDesiredReplicas(sClient, gr, resourceName, namespace, int32(newSize)))
|
|
||||||
if err == wait.ErrWaitTimeout {
|
|
||||||
return fmt.Errorf("timed out waiting for %q to be synced", resourceName)
|
return fmt.Errorf("timed out waiting for %q to be synced", resourceName)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package scale
|
package scale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
@ -69,7 +70,7 @@ func TestReplicationControllerScaleRetry(t *testing.T) {
|
|||||||
namespace := metav1.NamespaceDefault
|
namespace := metav1.NamespaceDefault
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rcgvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rcgvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass {
|
if pass {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ func TestReplicationControllerScaleRetry(t *testing.T) {
|
|||||||
}
|
}
|
||||||
preconditions := ScalePrecondition{3, ""}
|
preconditions := ScalePrecondition{3, ""}
|
||||||
scaleFunc = ScaleCondition(scaler, &preconditions, namespace, name, count, nil, rcgvr, false)
|
scaleFunc = ScaleCondition(scaler, &preconditions, namespace, name, count, nil, rcgvr, false)
|
||||||
_, err = scaleFunc()
|
_, err = scaleFunc(context.Background())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected error on precondition failure")
|
t.Errorf("Expected error on precondition failure")
|
||||||
}
|
}
|
||||||
@ -105,7 +106,7 @@ func TestReplicationControllerScaleInvalid(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rcgvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rcgvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass {
|
if pass {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -179,7 +180,7 @@ func TestDeploymentScaleRetry(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, deploygvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, deploygvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass != false {
|
if pass != false {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -188,7 +189,7 @@ func TestDeploymentScaleRetry(t *testing.T) {
|
|||||||
}
|
}
|
||||||
preconditions := &ScalePrecondition{3, ""}
|
preconditions := &ScalePrecondition{3, ""}
|
||||||
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, deploygvr, false)
|
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, deploygvr, false)
|
||||||
_, err = scaleFunc()
|
_, err = scaleFunc(context.Background())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error on precondition failure")
|
t.Error("Expected error on precondition failure")
|
||||||
}
|
}
|
||||||
@ -236,7 +237,7 @@ func TestDeploymentScaleInvalid(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, deploygvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, deploygvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass {
|
if pass {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -309,7 +310,7 @@ func TestStatefulSetScaleRetry(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, stsgvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, stsgvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass != false {
|
if pass != false {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -318,7 +319,7 @@ func TestStatefulSetScaleRetry(t *testing.T) {
|
|||||||
}
|
}
|
||||||
preconditions := &ScalePrecondition{3, ""}
|
preconditions := &ScalePrecondition{3, ""}
|
||||||
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, stsgvr, false)
|
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, stsgvr, false)
|
||||||
_, err = scaleFunc()
|
_, err = scaleFunc(context.Background())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error on precondition failure")
|
t.Error("Expected error on precondition failure")
|
||||||
}
|
}
|
||||||
@ -345,7 +346,7 @@ func TestStatefulSetScaleInvalid(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, stsgvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, stsgvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass {
|
if pass {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -418,7 +419,7 @@ func TestReplicaSetScaleRetry(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rsgvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rsgvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass != false {
|
if pass != false {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
@ -427,7 +428,7 @@ func TestReplicaSetScaleRetry(t *testing.T) {
|
|||||||
}
|
}
|
||||||
preconditions := &ScalePrecondition{3, ""}
|
preconditions := &ScalePrecondition{3, ""}
|
||||||
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, rsgvr, false)
|
scaleFunc = ScaleCondition(scaler, preconditions, namespace, name, count, nil, rsgvr, false)
|
||||||
_, err = scaleFunc()
|
_, err = scaleFunc(context.Background())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Expected error on precondition failure")
|
t.Error("Expected error on precondition failure")
|
||||||
}
|
}
|
||||||
@ -454,7 +455,7 @@ func TestReplicaSetScaleInvalid(t *testing.T) {
|
|||||||
namespace := "default"
|
namespace := "default"
|
||||||
|
|
||||||
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rsgvr, false)
|
scaleFunc := ScaleCondition(scaler, nil, namespace, name, count, nil, rsgvr, false)
|
||||||
pass, err := scaleFunc()
|
pass, err := scaleFunc(context.Background())
|
||||||
if pass {
|
if pass {
|
||||||
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
t.Errorf("Expected an update failure to return pass = false, got pass = %v", pass)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -35,9 +36,9 @@ const (
|
|||||||
waitRetryTimeout = 5 * time.Minute
|
waitRetryTimeout = 5 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
func RetryErrorCondition(condition wait.ConditionFunc) wait.ConditionFunc {
|
func RetryErrorCondition(condition wait.ConditionWithContextFunc) wait.ConditionWithContextFunc {
|
||||||
return func() (bool, error) {
|
return func(ctx context.Context) (bool, error) {
|
||||||
done, err := condition()
|
done, err := condition(ctx)
|
||||||
return done, err
|
return done, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +51,7 @@ func ScaleResourceWithRetries(scalesGetter scaleclient.ScalesGetter, namespace,
|
|||||||
}
|
}
|
||||||
waitForReplicas := scale.NewRetryParams(waitRetryInterval, waitRetryTimeout)
|
waitForReplicas := scale.NewRetryParams(waitRetryInterval, waitRetryTimeout)
|
||||||
cond := RetryErrorCondition(scale.ScaleCondition(scaler, preconditions, namespace, name, size, nil, gvr, false))
|
cond := RetryErrorCondition(scale.ScaleCondition(scaler, preconditions, namespace, name, size, nil, gvr, false))
|
||||||
err := wait.PollImmediate(updateRetryInterval, updateRetryTimeout, cond)
|
err := wait.PollUntilContextTimeout(context.Background(), updateRetryInterval, updateRetryTimeout, true, cond)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = scale.WaitForScaleHasDesiredReplicas(scalesGetter, gvr.GroupResource(), name, namespace, size, waitForReplicas)
|
err = scale.WaitForScaleHasDesiredReplicas(scalesGetter, gvr.GroupResource(), name, namespace, size, waitForReplicas)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user