@@ -18,6 +18,7 @@ package internal
18
18
19
19
import (
20
20
"fmt"
21
+ "math/rand"
21
22
"sync"
22
23
"time"
23
24
@@ -92,7 +93,9 @@ type specificInformersMap struct {
92
93
// stop is the stop channel to stop informers
93
94
stop <- chan struct {}
94
95
95
- // resync is the frequency the informers are resynced
96
+ // resync is the base frequency the informers are resynced
97
+ // a 10 percent jitter will be added to the resync period between informers
98
+ // so that all informers will not send list requests simultaneously.
96
99
resync time.Duration
97
100
98
101
// mu guards access to the map
@@ -188,7 +191,7 @@ func (ip *specificInformersMap) addInformerToMap(gvk schema.GroupVersionKind, ob
188
191
if err != nil {
189
192
return nil , false , err
190
193
}
191
- ni := cache .NewSharedIndexInformer (lw , obj , ip .resync , cache.Indexers {
194
+ ni := cache .NewSharedIndexInformer (lw , obj , resyncPeriod ( ip .resync )() , cache.Indexers {
192
195
cache .NamespaceIndex : cache .MetaNamespaceIndexFunc ,
193
196
})
194
197
i := & MapEntry {
@@ -274,3 +277,14 @@ func createUnstructuredListWatch(gvk schema.GroupVersionKind, ip *specificInform
274
277
},
275
278
}, nil
276
279
}
280
+
281
+ // resyncPeriod returns a function which generates a duration each time it is
282
+ // invoked; this is so that multiple controllers don't get into lock-step and all
283
+ // hammer the apiserver with list requests simultaneously.
284
+ func resyncPeriod (resync time.Duration ) func () time.Duration {
285
+ return func () time.Duration {
286
+ // the factor will fall into [0.9, 1.1)
287
+ factor := rand .Float64 ()/ 5.0 + 0.9
288
+ return time .Duration (float64 (resync .Nanoseconds ()) * factor )
289
+ }
290
+ }
0 commit comments