reflector: fallback to the previous mode on any error

originally we honored only apierrors.IsInvalid
but decided to fallback on every error
because it is better to make progress than deadlocking

Kubernetes-commit: 4b3915017950a114124a88c5d308bd8bfb9ec48e
This commit is contained in:
Lukasz Szaszkiewicz 2023-10-04 08:17:10 +02:00 committed by Kubernetes Publisher
parent fbb1575728
commit 1e0855a7ac
2 changed files with 33 additions and 15 deletions

View File

@ -334,12 +334,9 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
return nil
}
if err != nil {
if !apierrors.IsInvalid(err) {
return err
}
klog.Warning("The watch-list feature is not supported by the server, falling back to the previous LIST/WATCH semantics")
klog.Warningf("The watchlist request ended with an error, falling back to the standard LIST/WATCH semantics because making progress is better than deadlocking, err = %v", err)
fallbackToList = true
// Ensure that we won't accidentally pass some garbage down the watch.
// ensure that we won't accidentally pass some garbage down the watch.
w = nil
}
}

View File

@ -94,18 +94,39 @@ func TestWatchList(t *testing.T) {
expectedStoreContent: []v1.Pod{*makePod("p1", "1")},
},
{
name: "returning any other error than apierrors.NewInvalid stops the reflector and reports the error",
name: "returning any other error than apierrors.NewInvalid forces fallback",
watchOptionsPredicate: func(options metav1.ListOptions) error {
if options.SendInitialEvents != nil && *options.SendInitialEvents {
return fmt.Errorf("dummy error")
}
return nil
},
expectedError: fmt.Errorf("dummy error"),
expectedWatchRequests: 1,
expectedRequestOptions: []metav1.ListOptions{{
podList: &v1.PodList{
ListMeta: metav1.ListMeta{ResourceVersion: "1"},
Items: []v1.Pod{*makePod("p1", "1")},
},
closeAfterWatchEvents: 1,
watchEvents: []watch.Event{{Type: watch.Added, Object: makePod("p2", "2")}},
expectedWatchRequests: 2,
expectedListRequests: 1,
expectedStoreContent: []v1.Pod{*makePod("p1", "1"), *makePod("p2", "2")},
expectedRequestOptions: []metav1.ListOptions{
{
SendInitialEvents: pointer.Bool(true),
AllowWatchBookmarks: true,
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
TimeoutSeconds: pointer.Int64(1),
}},
},
{
ResourceVersion: "0",
Limit: 500,
},
{
AllowWatchBookmarks: true,
ResourceVersion: "1",
TimeoutSeconds: pointer.Int64(1),
},
},
},
{
name: "the reflector can fall back to old LIST/WATCH semantics when a server doesn't support streaming",