@@ -463,31 +463,19 @@ func NewCacherFromConfig(config Config) (*Cacher, error) {
463
463
}
464
464
465
465
func (c * Cacher ) startCaching (stopChannel <- chan struct {}) {
466
- // The 'usable' lock is always 'RLock'able when it is safe to use the cache.
467
- // It is safe to use the cache after a successful list until a disconnection.
468
- // We start with usable (write) locked. The below OnReplace function will
469
- // unlock it after a successful list. The below defer will then re-lock
470
- // it when this function exits (always due to disconnection), only if
471
- // we actually got a successful list. This cycle will repeat as needed.
472
- successfulList := false
473
466
c .watchCache .SetOnReplace (func () {
474
- successfulList = true
475
- c .ready .set (true )
467
+ c .ready .setReady ()
476
468
klog .V (1 ).Infof ("cacher (%v): initialized" , c .groupResource .String ())
477
469
metrics .WatchCacheInitializations .WithLabelValues (c .groupResource .String ()).Inc ()
478
470
})
471
+ var err error
479
472
defer func () {
480
- if successfulList {
481
- c .ready .set (false )
482
- }
473
+ c .ready .setError (err )
483
474
}()
484
475
485
476
c .terminateAllWatchers ()
486
- // Note that since onReplace may be not called due to errors, we explicitly
487
- // need to retry it on errors under lock.
488
- // Also note that startCaching is called in a loop, so there's no need
489
- // to have another loop here.
490
- if err := c .reflector .ListAndWatch (stopChannel ); err != nil {
477
+ err = c .reflector .ListAndWatch (stopChannel )
478
+ if err != nil {
491
479
klog .Errorf ("cacher (%v): unexpected ListAndWatch error: %v; reinitializing..." , c .groupResource .String (), err )
492
480
}
493
481
}
@@ -506,11 +494,11 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions
506
494
507
495
var readyGeneration int
508
496
if utilfeature .DefaultFeatureGate .Enabled (features .ResilientWatchCacheInitialization ) {
509
- var ok bool
497
+ var err error
510
498
var downtime time.Duration
511
- readyGeneration , downtime , ok = c .ready .checkAndReadGeneration ()
512
- if ! ok {
513
- return nil , errors .NewTooManyRequests ("storage is (re)initializing" , calculateRetryAfterForUnreadyCache (downtime ))
499
+ readyGeneration , downtime , err = c .ready .checkAndReadGeneration ()
500
+ if err != nil {
501
+ return nil , errors .NewTooManyRequests (err . Error () , calculateRetryAfterForUnreadyCache (downtime ))
514
502
}
515
503
} else {
516
504
readyGeneration , err = c .ready .waitAndReadGeneration (ctx )
@@ -631,7 +619,7 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions
631
619
c .Lock ()
632
620
defer c .Unlock ()
633
621
634
- if generation , _ , ok := c .ready .checkAndReadGeneration (); generation != readyGeneration || ! ok {
622
+ if generation , _ , err := c .ready .checkAndReadGeneration (); generation != readyGeneration || err != nil {
635
623
// We went unready or are already on a different generation.
636
624
// Avoid registering and starting the watch as it will have to be
637
625
// terminated immediately anyway.
@@ -749,10 +737,10 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio
749
737
defer span .End (500 * time .Millisecond )
750
738
751
739
if utilfeature .DefaultFeatureGate .Enabled (features .ResilientWatchCacheInitialization ) {
752
- if downtime , ok := c .ready .check (); ! ok {
740
+ if downtime , err := c .ready .check (); err != nil {
753
741
// If Cacher is not initialized, reject List requests
754
742
// as described in https://kep.k8s.io/4568
755
- return errors .NewTooManyRequests ("storage is (re)initializing" , calculateRetryAfterForUnreadyCache (downtime ))
743
+ return errors .NewTooManyRequests (err . Error () , calculateRetryAfterForUnreadyCache (downtime ))
756
744
}
757
745
} else {
758
746
if err := c .ready .wait (ctx ); err != nil {
@@ -1304,8 +1292,8 @@ func (c *Cacher) setInitialEventsEndBookmarkIfRequested(cacheInterval *watchCach
1304
1292
}
1305
1293
1306
1294
func (c * Cacher ) Ready () bool {
1307
- _ , ok := c .ready .check ()
1308
- return ok
1295
+ _ , err := c .ready .check ()
1296
+ return err == nil
1309
1297
}
1310
1298
1311
1299
// errWatcher implements watch.Interface to return a single error
0 commit comments