Skip to content

Commit 017379f

Browse files
authored
Merge pull request #6664 from XiShanYongYe-Chang/add-comments-for-serviceexport-controller
add comments for service-export-controller
2 parents 1c6f1db + 2e121f1 commit 017379f

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

pkg/controllers/mcs/service_export_controller.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ import (
6464
const ServiceExportControllerName = "service-export-controller"
6565

6666
// ServiceExportController is to sync ServiceExport and report EndpointSlices of exported service to control-plane.
67+
// It creates Informers for clusters where ServiceExport resources have been propagated,
68+
// registers EventHandlers for ServiceExport and EndpointSlice in those clusters,
69+
// and then asynchronously processes ServiceExport and EndpointSlice events.
6770
type ServiceExportController struct {
6871
client.Client
6972
EventRecorder record.EventRecorder
@@ -112,6 +115,7 @@ func (c *ServiceExportController) Reconcile(ctx context.Context, req controllerr
112115
return controllerruntime.Result{}, nil
113116
}
114117

118+
// Controller should only handle ServiceExport Works, reduces noise and prevents unnecessary processing.
115119
if !util.IsWorkContains(work.Spec.Workload.Manifests, serviceExportGVK) {
116120
return controllerruntime.Result{}, nil
117121
}
@@ -139,7 +143,9 @@ func (c *ServiceExportController) Reconcile(ctx context.Context, req controllerr
139143

140144
// SetupWithManager creates a controller and register to controller manager.
141145
func (c *ServiceExportController) SetupWithManager(mgr controllerruntime.Manager) error {
142-
return controllerruntime.NewControllerManagedBy(mgr).Named(ServiceExportControllerName).For(&workv1alpha1.Work{}, builder.WithPredicates(c.PredicateFunc)).
146+
return controllerruntime.NewControllerManagedBy(mgr).
147+
Named(ServiceExportControllerName).
148+
For(&workv1alpha1.Work{}, builder.WithPredicates(c.PredicateFunc)).
143149
WithOptions(controller.Options{
144150
RateLimiter: ratelimiterflag.DefaultControllerRateLimiter[controllerruntime.Request](c.RateLimiterOptions),
145151
}).
@@ -156,6 +162,8 @@ func (c *ServiceExportController) RunWorkQueue() {
156162
c.worker = util.NewAsyncWorker(workerOptions)
157163
c.worker.Run(c.Context, c.WorkerNumber)
158164

165+
// TODO(@XiShanYongYe-Chang): Need to re-examine whether this call is necessary.
166+
// If it is necessary, clarify the reason; otherwise, delete this call.
159167
go c.enqueueReportedEpsServiceExport()
160168
}
161169

@@ -241,8 +249,8 @@ func (c *ServiceExportController) buildResourceInformers(cluster *clusterv1alpha
241249
return nil
242250
}
243251

244-
// registerInformersAndStart builds informer manager for cluster if it doesn't exist, then constructs informers for gvr
245-
// and start it.
252+
// registerInformersAndStart builds informer manager for cluster if it doesn't exist, then
253+
// constructs informers for gvr and start it.
246254
func (c *ServiceExportController) registerInformersAndStart(cluster *clusterv1alpha1.Cluster) error {
247255
singleClusterInformerManager := c.InformerManager.GetSingleClusterManager(cluster.Name)
248256
if singleClusterInformerManager == nil {
@@ -273,6 +281,7 @@ func (c *ServiceExportController) registerInformersAndStart(cluster *clusterv1al
273281
c.InformerManager.Start(cluster.Name)
274282

275283
if err := func() error {
284+
// this call is necessary; otherwise, `IsInformerSynced` will always return false.
276285
synced := c.InformerManager.WaitForCacheSyncWithTimeout(cluster.Name, c.ClusterCacheSyncTimeout.Duration)
277286
if synced == nil {
278287
return fmt.Errorf("no informerFactory for cluster %s exist", cluster.Name)
@@ -362,8 +371,9 @@ func (c *ServiceExportController) handleServiceExportEvent(ctx context.Context,
362371

363372
// Even though the EndpointSlice will be synced when dealing with EndpointSlice events, thus the 'report' here may
364373
// be redundant, but it helps to avoid a corner case:
365-
// If skip report here, after ServiceExport deletion and re-creation, if no EndpointSlice changes, we didn't get a
366-
// change to sync.
374+
// When ServiceExport is created after Service in member cluster, and EndpointSlice events have been processed,
375+
// if we don't handle the ServiceExport event, the EndpointSlice will not be collected to the control plane,
376+
// unless a new EndpointSlice event is received.
367377
if err = c.reportEndpointSliceWithServiceExportCreate(ctx, serviceExportKey); err != nil {
368378
klog.ErrorS(err, "Failed to handle ServiceExport event", "namespace", serviceExportKey.Namespace, "name", serviceExportKey.Name)
369379
return err
@@ -393,6 +403,8 @@ func (c *ServiceExportController) handleEndpointSliceEvent(ctx context.Context,
393403
}
394404

395405
// reportEndpointSliceWithServiceExportCreate reports the referencing service's EndpointSlice.
406+
// The informer for EndpointSlice is created dynamically in Reconcile() when ServiceExport Works are detected.
407+
// If informer isn't synced yet, we return error to trigger retry.
396408
func (c *ServiceExportController) reportEndpointSliceWithServiceExportCreate(ctx context.Context, serviceExportKey keys.FederatedKey) error {
397409
var (
398410
endpointSliceObjects []runtime.Object
@@ -402,6 +414,8 @@ func (c *ServiceExportController) reportEndpointSliceWithServiceExportCreate(ctx
402414

403415
singleClusterManager := c.InformerManager.GetSingleClusterManager(serviceExportKey.Cluster)
404416
if singleClusterManager == nil {
417+
// No informer manager for this cluster yet - this shouldn't happen
418+
// if Reconcile() has run, but handle gracefully
405419
return nil
406420
}
407421

@@ -433,6 +447,7 @@ func (c *ServiceExportController) reportEndpointSliceWithServiceExportCreate(ctx
433447
return utilerrors.NewAggregate(errs)
434448
}
435449

450+
// removeOrphanWork cleans up Work resources for EndpointSlices that no longer exist.
436451
func (c *ServiceExportController) removeOrphanWork(ctx context.Context, endpointSliceObjects []runtime.Object, serviceExportKey keys.FederatedKey) error {
437452
willReportWorks := sets.NewString()
438453
for index := range endpointSliceObjects {
@@ -481,6 +496,8 @@ func (c *ServiceExportController) removeOrphanWork(ctx context.Context, endpoint
481496
}
482497

483498
// reportEndpointSliceWithEndpointSliceCreateOrUpdate reports the EndpointSlice when referencing service has been exported.
499+
// The informer for ServiceExport is created dynamically in Reconcile() when ServiceExport Works are detected.
500+
// If informer isn't synced yet, we return error to trigger retry.
484501
func (c *ServiceExportController) reportEndpointSliceWithEndpointSliceCreateOrUpdate(ctx context.Context, clusterName string, endpointSlice *unstructured.Unstructured) error {
485502
relatedServiceName := endpointSlice.GetLabels()[discoveryv1.LabelServiceName]
486503

0 commit comments

Comments
 (0)