mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #18499 from wojtek-t/fix_reflector_race
Auto commit by PR queue bot
This commit is contained in:
		
							
								
								
									
										11
									
								
								pkg/client/cache/reflector.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								pkg/client/cache/reflector.go
									
									
									
									
										vendored
									
									
								
							@@ -63,6 +63,8 @@ type Reflector struct {
 | 
				
			|||||||
	// the beginning of the next one.
 | 
						// the beginning of the next one.
 | 
				
			||||||
	period       time.Duration
 | 
						period       time.Duration
 | 
				
			||||||
	resyncPeriod time.Duration
 | 
						resyncPeriod time.Duration
 | 
				
			||||||
 | 
						// now() returns current time - exposed for testing purposes
 | 
				
			||||||
 | 
						now func() time.Time
 | 
				
			||||||
	// nextResync is approximate time of next resync (0 if not scheduled)
 | 
						// nextResync is approximate time of next resync (0 if not scheduled)
 | 
				
			||||||
	nextResync time.Time
 | 
						nextResync time.Time
 | 
				
			||||||
	// lastSyncResourceVersion is the resource version token last
 | 
						// lastSyncResourceVersion is the resource version token last
 | 
				
			||||||
@@ -79,8 +81,6 @@ var (
 | 
				
			|||||||
	// However, it can be modified to avoid periodic resync to break the
 | 
						// However, it can be modified to avoid periodic resync to break the
 | 
				
			||||||
	// TCP connection.
 | 
						// TCP connection.
 | 
				
			||||||
	minWatchTimeout = 5 * time.Minute
 | 
						minWatchTimeout = 5 * time.Minute
 | 
				
			||||||
 | 
					 | 
				
			||||||
	now func() time.Time = time.Now
 | 
					 | 
				
			||||||
	// If we are within 'forceResyncThreshold' from the next planned resync
 | 
						// If we are within 'forceResyncThreshold' from the next planned resync
 | 
				
			||||||
	// and are just before issueing Watch(), resync will be forced now.
 | 
						// and are just before issueing Watch(), resync will be forced now.
 | 
				
			||||||
	forceResyncThreshold = 3 * time.Second
 | 
						forceResyncThreshold = 3 * time.Second
 | 
				
			||||||
@@ -116,6 +116,7 @@ func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{},
 | 
				
			|||||||
		expectedType:  reflect.TypeOf(expectedType),
 | 
							expectedType:  reflect.TypeOf(expectedType),
 | 
				
			||||||
		period:        time.Second,
 | 
							period:        time.Second,
 | 
				
			||||||
		resyncPeriod:  resyncPeriod,
 | 
							resyncPeriod:  resyncPeriod,
 | 
				
			||||||
 | 
							now:           time.Now,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return r
 | 
						return r
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -187,7 +188,7 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) {
 | 
				
			|||||||
	// always fail so we end up listing frequently. Then, if we don't
 | 
						// always fail so we end up listing frequently. Then, if we don't
 | 
				
			||||||
	// manually stop the timer, we could end up with many timers active
 | 
						// manually stop the timer, we could end up with many timers active
 | 
				
			||||||
	// concurrently.
 | 
						// concurrently.
 | 
				
			||||||
	r.nextResync = now().Add(r.resyncPeriod)
 | 
						r.nextResync = r.now().Add(r.resyncPeriod)
 | 
				
			||||||
	t := time.NewTimer(r.resyncPeriod)
 | 
						t := time.NewTimer(r.resyncPeriod)
 | 
				
			||||||
	return t.C, t.Stop
 | 
						return t.C, t.Stop
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -204,7 +205,7 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) {
 | 
				
			|||||||
// TODO: This should be parametrizable based on server load.
 | 
					// TODO: This should be parametrizable based on server load.
 | 
				
			||||||
func (r *Reflector) timeoutForWatch() *int64 {
 | 
					func (r *Reflector) timeoutForWatch() *int64 {
 | 
				
			||||||
	randTimeout := time.Duration(float64(minWatchTimeout) * (rand.Float64() + 1.0))
 | 
						randTimeout := time.Duration(float64(minWatchTimeout) * (rand.Float64() + 1.0))
 | 
				
			||||||
	timeout := r.nextResync.Sub(now()) - timeoutThreshold
 | 
						timeout := r.nextResync.Sub(r.now()) - timeoutThreshold
 | 
				
			||||||
	if timeout < 0 || randTimeout < timeout {
 | 
						if timeout < 0 || randTimeout < timeout {
 | 
				
			||||||
		timeout = randTimeout
 | 
							timeout = randTimeout
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -218,7 +219,7 @@ func (r *Reflector) canForceResyncNow() bool {
 | 
				
			|||||||
	if r.nextResync.IsZero() {
 | 
						if r.nextResync.IsZero() {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return now().Add(forceResyncThreshold).After(r.nextResync)
 | 
						return r.now().Add(forceResyncThreshold).After(r.nextResync)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns error if ListAndWatch didn't even tried to initialize watch.
 | 
					// Returns error if ListAndWatch didn't even tried to initialize watch.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								pkg/client/cache/reflector_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								pkg/client/cache/reflector_test.go
									
									
									
									
										vendored
									
									
								
							@@ -367,7 +367,6 @@ func TestReflectorResync(t *testing.T) {
 | 
				
			|||||||
	s := NewStore(MetaNamespaceKeyFunc)
 | 
						s := NewStore(MetaNamespaceKeyFunc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	currentTime := time.Time{}
 | 
						currentTime := time.Time{}
 | 
				
			||||||
	now = func() time.Time { return currentTime }
 | 
					 | 
				
			||||||
	iteration := 0
 | 
						iteration := 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lw := &testLW{
 | 
						lw := &testLW{
 | 
				
			||||||
@@ -396,6 +395,7 @@ func TestReflectorResync(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	resyncPeriod := time.Minute
 | 
						resyncPeriod := time.Minute
 | 
				
			||||||
	r := NewReflector(lw, &api.Pod{}, s, resyncPeriod)
 | 
						r := NewReflector(lw, &api.Pod{}, s, resyncPeriod)
 | 
				
			||||||
 | 
						r.now = func() time.Time { return currentTime }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.ListAndWatch(util.NeverStop)
 | 
						r.ListAndWatch(util.NeverStop)
 | 
				
			||||||
	if iteration != 2 {
 | 
						if iteration != 2 {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user