@@ -63,7 +63,7 @@ const (
63
63
func NewController (podInformer coreinformers.PodInformer ,
64
64
serviceInformer coreinformers.ServiceInformer ,
65
65
nodeInformer coreinformers.NodeInformer ,
66
- esInformer discoveryinformers.EndpointSliceInformer ,
66
+ endpointSliceInformer discoveryinformers.EndpointSliceInformer ,
67
67
maxEndpointsPerSlice int32 ,
68
68
client clientset.Interface ,
69
69
) * Controller {
@@ -105,15 +105,23 @@ func NewController(podInformer coreinformers.PodInformer,
105
105
c .nodeLister = nodeInformer .Lister ()
106
106
c .nodesSynced = nodeInformer .Informer ().HasSynced
107
107
108
- c .endpointSliceLister = esInformer .Lister ()
109
- c .endpointSlicesSynced = esInformer .Informer ().HasSynced
108
+ endpointSliceInformer .Informer ().AddEventHandler (cache.ResourceEventHandlerFuncs {
109
+ AddFunc : c .onEndpointSliceAdd ,
110
+ UpdateFunc : c .onEndpointSliceUpdate ,
111
+ DeleteFunc : c .onEndpointSliceDelete ,
112
+ })
113
+
114
+ c .endpointSliceLister = endpointSliceInformer .Lister ()
115
+ c .endpointSlicesSynced = endpointSliceInformer .Informer ().HasSynced
116
+ c .endpointSliceTracker = newEndpointSliceTracker ()
110
117
111
118
c .maxEndpointsPerSlice = maxEndpointsPerSlice
112
119
113
120
c .reconciler = & reconciler {
114
121
client : c .client ,
115
122
nodeLister : c .nodeLister ,
116
123
maxEndpointsPerSlice : c .maxEndpointsPerSlice ,
124
+ endpointSliceTracker : c .endpointSliceTracker ,
117
125
metricsCache : endpointslicemetrics .NewCache (maxEndpointsPerSlice ),
118
126
}
119
127
c .triggerTimeTracker = endpointutil .NewTriggerTimeTracker ()
@@ -152,6 +160,10 @@ type Controller struct {
152
160
// endpointSlicesSynced returns true if the endpoint slice shared informer has been synced at least once.
153
161
// Added as a member to the struct to allow injection for testing.
154
162
endpointSlicesSynced cache.InformerSynced
163
+ // endpointSliceTracker tracks the list of EndpointSlices and associated
164
+ // resource versions expected for each Service. It can help determine if a
165
+ // cached EndpointSlice is out of date.
166
+ endpointSliceTracker * endpointSliceTracker
155
167
156
168
// nodeLister is able to list/get nodes and is populated by the
157
169
// shared informer passed to NewController
@@ -343,6 +355,57 @@ func (c *Controller) onServiceDelete(obj interface{}) {
343
355
c .queue .Add (key )
344
356
}
345
357
358
+ // onEndpointSliceAdd queues a sync for the relevant Service for a sync if the
359
+ // EndpointSlice resource version does not match the expected version in the
360
+ // endpointSliceTracker.
361
+ func (c * Controller ) onEndpointSliceAdd (obj interface {}) {
362
+ endpointSlice := obj .(* discovery.EndpointSlice )
363
+ if endpointSlice == nil {
364
+ utilruntime .HandleError (fmt .Errorf ("Invalid EndpointSlice provided to onEndpointSliceAdd()" ))
365
+ return
366
+ }
367
+ if managedByController (endpointSlice ) && c .endpointSliceTracker .Stale (endpointSlice ) {
368
+ c .queueServiceForEndpointSlice (endpointSlice )
369
+ }
370
+ }
371
+
372
+ // onEndpointSliceUpdate queues a sync for the relevant Service for a sync if
373
+ // the EndpointSlice resource version does not match the expected version in the
374
+ // endpointSliceTracker or the managed-by value of the EndpointSlice has changed
375
+ // from or to this controller.
376
+ func (c * Controller ) onEndpointSliceUpdate (prevObj , obj interface {}) {
377
+ prevEndpointSlice := obj .(* discovery.EndpointSlice )
378
+ endpointSlice := obj .(* discovery.EndpointSlice )
379
+ if endpointSlice == nil || prevEndpointSlice == nil {
380
+ utilruntime .HandleError (fmt .Errorf ("Invalid EndpointSlice provided to onEndpointSliceUpdate()" ))
381
+ return
382
+ }
383
+ if managedByChanged (prevEndpointSlice , endpointSlice ) || (managedByController (endpointSlice ) && c .endpointSliceTracker .Stale (endpointSlice )) {
384
+ c .queueServiceForEndpointSlice (endpointSlice )
385
+ }
386
+ }
387
+
388
+ // onEndpointSliceDelete queues a sync for the relevant Service for a sync if the
389
+ // EndpointSlice resource version does not match the expected version in the
390
+ // endpointSliceTracker.
391
+ func (c * Controller ) onEndpointSliceDelete (obj interface {}) {
392
+ endpointSlice := getEndpointSliceFromDeleteAction (obj )
393
+ if endpointSlice != nil && managedByController (endpointSlice ) && c .endpointSliceTracker .Has (endpointSlice ) {
394
+ c .queueServiceForEndpointSlice (endpointSlice )
395
+ }
396
+ }
397
+
398
+ // queueServiceForEndpointSlice attempts to queue the corresponding Service for
399
+ // the provided EndpointSlice.
400
+ func (c * Controller ) queueServiceForEndpointSlice (endpointSlice * discovery.EndpointSlice ) {
401
+ key , err := serviceControllerKey (endpointSlice )
402
+ if err != nil {
403
+ utilruntime .HandleError (fmt .Errorf ("Couldn't get key for EndpointSlice %+v: %v" , endpointSlice , err ))
404
+ return
405
+ }
406
+ c .queue .Add (key )
407
+ }
408
+
346
409
func (c * Controller ) addPod (obj interface {}) {
347
410
pod := obj .(* v1.Pod )
348
411
services , err := c .serviceSelectorCache .GetPodServiceMemberships (c .serviceLister , pod )
0 commit comments