mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-27 07:28:14 +00:00
Merge pull request #115093 from xuzhenglun/too-large-resource-version-1.16
Fix bug in reflector not detecting "Too large resource version" error before 1.17.0 Kubernetes-commit: d3f881f7508ec3bd8aa83712038bdcf5f4703396
This commit is contained in:
commit
e6998df99e
7
tools/cache/reflector.go
vendored
7
tools/cache/reflector.go
vendored
@ -23,6 +23,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -693,5 +694,11 @@ func isTooLargeResourceVersionError(err error) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Matches the message returned by api server before 1.17.0
|
||||||
|
if strings.Contains(apierr.Status().Message, "Too large resource version") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
13
tools/cache/reflector_test.go
vendored
13
tools/cache/reflector_test.go
vendored
@ -919,6 +919,7 @@ func TestReflectorFullListIfTooLarge(t *testing.T) {
|
|||||||
stopCh := make(chan struct{})
|
stopCh := make(chan struct{})
|
||||||
s := NewStore(MetaNamespaceKeyFunc)
|
s := NewStore(MetaNamespaceKeyFunc)
|
||||||
listCallRVs := []string{}
|
listCallRVs := []string{}
|
||||||
|
version := 30
|
||||||
|
|
||||||
lw := &testLW{
|
lw := &testLW{
|
||||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||||
@ -929,6 +930,7 @@ func TestReflectorFullListIfTooLarge(t *testing.T) {
|
|||||||
},
|
},
|
||||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||||
listCallRVs = append(listCallRVs, options.ResourceVersion)
|
listCallRVs = append(listCallRVs, options.ResourceVersion)
|
||||||
|
resourceVersion := strconv.Itoa(version)
|
||||||
|
|
||||||
switch options.ResourceVersion {
|
switch options.ResourceVersion {
|
||||||
// initial list
|
// initial list
|
||||||
@ -944,9 +946,14 @@ func TestReflectorFullListIfTooLarge(t *testing.T) {
|
|||||||
err := apierrors.NewTimeoutError("too large resource version", 1)
|
err := apierrors.NewTimeoutError("too large resource version", 1)
|
||||||
err.ErrStatus.Details.Causes = []metav1.StatusCause{{Message: "Too large resource version"}}
|
err.ErrStatus.Details.Causes = []metav1.StatusCause{{Message: "Too large resource version"}}
|
||||||
return nil, err
|
return nil, err
|
||||||
|
// relist after the initial list (covers the error format used in api server before 1.17.0)
|
||||||
|
case "40":
|
||||||
|
err := apierrors.NewTimeoutError("Too large resource version", 1)
|
||||||
|
return nil, err
|
||||||
// relist from etcd after "too large" error
|
// relist from etcd after "too large" error
|
||||||
case "":
|
case "":
|
||||||
return &v1.PodList{ListMeta: metav1.ListMeta{ResourceVersion: "30"}}, nil
|
version += 10
|
||||||
|
return &v1.PodList{ListMeta: metav1.ListMeta{ResourceVersion: resourceVersion}}, nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected List call: %s", options.ResourceVersion)
|
return nil, fmt.Errorf("unexpected List call: %s", options.ResourceVersion)
|
||||||
}
|
}
|
||||||
@ -965,7 +972,7 @@ func TestReflectorFullListIfTooLarge(t *testing.T) {
|
|||||||
// may be synced to a different version and they will never converge.
|
// may be synced to a different version and they will never converge.
|
||||||
// TODO: We should use etcd progress-notify feature to avoid this behavior but until this is
|
// TODO: We should use etcd progress-notify feature to avoid this behavior but until this is
|
||||||
// done we simply try to relist from now to avoid continuous errors on relists.
|
// done we simply try to relist from now to avoid continuous errors on relists.
|
||||||
for i := 1; i <= 2; i++ {
|
for i := 1; i <= 3; i++ {
|
||||||
// relist twice to cover the two variants of TooLargeResourceVersion api errors
|
// relist twice to cover the two variants of TooLargeResourceVersion api errors
|
||||||
stopCh = make(chan struct{})
|
stopCh = make(chan struct{})
|
||||||
if err := r.ListAndWatch(stopCh); err != nil {
|
if err := r.ListAndWatch(stopCh); err != nil {
|
||||||
@ -973,7 +980,7 @@ func TestReflectorFullListIfTooLarge(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedRVs := []string{"0", "20", "", "30", ""}
|
expectedRVs := []string{"0", "20", "", "30", "", "40", ""}
|
||||||
if !reflect.DeepEqual(listCallRVs, expectedRVs) {
|
if !reflect.DeepEqual(listCallRVs, expectedRVs) {
|
||||||
t.Errorf("Expected series of list calls with resource version of %#v but got: %#v", expectedRVs, listCallRVs)
|
t.Errorf("Expected series of list calls with resource version of %#v but got: %#v", expectedRVs, listCallRVs)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user