@@ -114,6 +114,9 @@ func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{},
114
114
period : time .Second ,
115
115
resyncPeriod : resyncPeriod ,
116
116
clock : & clock.RealClock {},
117
+ // We set lastSyncResourceVersion to "0", because it's the value which
118
+ // we set as ResourceVersion to the first List() request.
119
+ lastSyncResourceVersion : "0" ,
117
120
}
118
121
r .setExpectedType (expectedType )
119
122
return r
@@ -185,10 +188,16 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
185
188
klog .V (3 ).Infof ("Listing and watching %v from %s" , r .expectedTypeName , r .name )
186
189
var resourceVersion string
187
190
188
- // Explicitly set "0" as resource version - it's fine for the List()
189
- // to be served from cache and potentially be delayed relative to
190
- // etcd contents. Reflector framework will catch up via Watch() eventually.
191
- options := metav1.ListOptions {ResourceVersion : "0" }
191
+ // Explicitly set resource version to have it list from cache for
192
+ // performance reasons.
193
+ // It's fine for the returned state to be stale (we will catch up via
194
+ // Watch() eventually), but can't set "0" to avoid going back in time
195
+ // if we hit apiserver that is significantly delayed compared to the
196
+ // state we already had.
197
+ // TODO: There is still a potential to go back in time after component
198
+ // restart when we set ResourceVersion: "0". For more details see:
199
+ // https://github.com/kubernetes/kubernetes/issues/59848
200
+ options := metav1.ListOptions {ResourceVersion : r .LastSyncResourceVersion ()}
192
201
193
202
if err := func () error {
194
203
initTrace := trace .New ("Reflector ListAndWatch" , trace.Field {"name" , r .name })
0 commit comments