@@ -82,9 +82,9 @@ type Reflector struct {
82
82
// observed when doing a sync with the underlying store
83
83
// it is thread safe, but not synchronized with the underlying store
84
84
lastSyncResourceVersion string
85
- // isLastSyncResourceVersionGone is true if the previous list or watch request with lastSyncResourceVersion
86
- // failed with an HTTP 410 (Gone) status code .
87
- isLastSyncResourceVersionGone bool
85
+ // isLastSyncResourceVersionUnavailable is true if the previous list or watch request with
86
+ // lastSyncResourceVersion failed with an "expired" or "too large resource version" error .
87
+ isLastSyncResourceVersionUnavailable bool
88
88
// lastSyncResourceVersionMutex guards read/write access to lastSyncResourceVersion
89
89
lastSyncResourceVersionMutex sync.RWMutex
90
90
// WatchListPageSize is the requested chunk size of initial and resync watch lists.
@@ -115,7 +115,7 @@ type WatchErrorHandler func(r *Reflector, err error)
115
115
func DefaultWatchErrorHandler (r * Reflector , err error ) {
116
116
switch {
117
117
case isExpiredError (err ):
118
- // Don't set LastSyncResourceVersionExpired - LIST call with ResourceVersion=RV already
118
+ // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already
119
119
// has a semantic that it returns data at least as fresh as provided RV.
120
120
// So first try to LIST with setting RV to resource version of last observed object.
121
121
klog .V (4 ).Infof ("%s: watch of %v closed with: %v" , r .name , r .expectedTypeName , err )
@@ -288,13 +288,14 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
288
288
}
289
289
290
290
list , paginatedResult , err = pager .List (context .Background (), options )
291
- if isExpiredError (err ) {
292
- r .setIsLastSyncResourceVersionExpired (true )
293
- // Retry immediately if the resource version used to list is expired .
291
+ if isExpiredError (err ) || isTooLargeResourceVersionError ( err ) {
292
+ r .setIsLastSyncResourceVersionUnavailable (true )
293
+ // Retry immediately if the resource version used to list is unavailable .
294
294
// The pager already falls back to full list if paginated list calls fail due to an "Expired" error on
295
- // continuation pages, but the pager might not be enabled, or the full list might fail because the
296
- // resource version it is listing at is expired, so we need to fallback to resourceVersion="" in all
297
- // to recover and ensure the reflector makes forward progress.
295
+ // continuation pages, but the pager might not be enabled, the full list might fail because the
296
+ // resource version it is listing at is expired or the cache may not yet be synced to the provided
297
+ // resource version. So we need to fallback to resourceVersion="" in all to recover and ensure
298
+ // the reflector makes forward progress.
298
299
list , paginatedResult , err = pager .List (context .Background (), metav1.ListOptions {ResourceVersion : r .relistResourceVersion ()})
299
300
}
300
301
close (listCh )
@@ -324,7 +325,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
324
325
r .paginatedResult = true
325
326
}
326
327
327
- r .setIsLastSyncResourceVersionExpired (false ) // list was successful
328
+ r .setIsLastSyncResourceVersionUnavailable (false ) // list was successful
328
329
initTrace .Step ("Objects listed" )
329
330
listMetaInterface , err := meta .ListAccessor (list )
330
331
if err != nil {
@@ -415,7 +416,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
415
416
if err != errorStopRequested {
416
417
switch {
417
418
case isExpiredError (err ):
418
- // Don't set LastSyncResourceVersionExpired - LIST call with ResourceVersion=RV already
419
+ // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already
419
420
// has a semantic that it returns data at least as fresh as provided RV.
420
421
// So first try to LIST with setting RV to resource version of last observed object.
421
422
klog .V (4 ).Infof ("%s: watch of %v closed with: %v" , r .name , r .expectedTypeName , err )
@@ -538,9 +539,9 @@ func (r *Reflector) relistResourceVersion() string {
538
539
r .lastSyncResourceVersionMutex .RLock ()
539
540
defer r .lastSyncResourceVersionMutex .RUnlock ()
540
541
541
- if r .isLastSyncResourceVersionGone {
542
+ if r .isLastSyncResourceVersionUnavailable {
542
543
// Since this reflector makes paginated list requests, and all paginated list requests skip the watch cache
543
- // if the lastSyncResourceVersion is expired , we set ResourceVersion="" and list again to re-establish reflector
544
+ // if the lastSyncResourceVersion is unavailable , we set ResourceVersion="" and list again to re-establish reflector
544
545
// to the latest available ResourceVersion, using a consistent read from etcd.
545
546
return ""
546
547
}
@@ -552,12 +553,12 @@ func (r *Reflector) relistResourceVersion() string {
552
553
return r .lastSyncResourceVersion
553
554
}
554
555
555
- // setIsLastSyncResourceVersionExpired sets if the last list or watch request with lastSyncResourceVersion returned a
556
- // expired error: HTTP 410 (Gone) Status Code .
557
- func (r * Reflector ) setIsLastSyncResourceVersionExpired ( isExpired bool ) {
556
+ // setIsLastSyncResourceVersionUnavailable sets if the last list or watch request with lastSyncResourceVersion returned
557
+ // " expired" or "too large resource version" error .
558
+ func (r * Reflector ) setIsLastSyncResourceVersionUnavailable ( isUnavailable bool ) {
558
559
r .lastSyncResourceVersionMutex .Lock ()
559
560
defer r .lastSyncResourceVersionMutex .Unlock ()
560
- r .isLastSyncResourceVersionGone = isExpired
561
+ r .isLastSyncResourceVersionUnavailable = isUnavailable
561
562
}
562
563
563
564
func isExpiredError (err error ) bool {
@@ -567,3 +568,7 @@ func isExpiredError(err error) bool {
567
568
// check when we fully drop support for Kubernetes 1.17 servers from reflectors.
568
569
return apierrors .IsResourceExpired (err ) || apierrors .IsGone (err )
569
570
}
571
+
572
+ func isTooLargeResourceVersionError (err error ) bool {
573
+ return apierrors .HasStatusCause (err , metav1 .CauseTypeResourceVersionTooLarge )
574
+ }
0 commit comments