in internal/controllers/watch/watch.go [43:95]
func (c *WatchController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := logr.FromContextOrDiscard(ctx)
synths := &apiv1.SynthesizerList{}
err := c.client.List(ctx, synths)
if err != nil {
logger.Error(err, "failed to list synthesizers")
return ctrl.Result{}, err
}
// It's important to randomize the order over which we iterate the synths,
// otherwise one bad resource reference can block the loop
rand.Shuffle(len(synths.Items), func(i, j int) { synths.Items[i], synths.Items[j] = synths.Items[j], synths.Items[i] })
// Start any missing controllers
synthsByRef := map[apiv1.ResourceRef]struct{}{}
for _, syn := range synths.Items {
if syn.DeletionTimestamp != nil {
continue
}
for _, ref := range syn.Spec.Refs {
ref := ref
synthsByRef[ref.Resource] = struct{}{}
current := c.refControllers[ref.Resource]
if current != nil {
continue // already running
}
rc, err := NewKindWatchController(ctx, c, &ref.Resource)
if err != nil {
logger.Error(err, "failed to create kind watch controller", "resource", ref.Resource)
return ctrl.Result{}, err
}
c.refControllers[ref.Resource] = rc
return ctrl.Result{Requeue: true}, nil
}
}
// Stop controllers that are no longer needed
for ref, rc := range c.refControllers {
if _, ok := synthsByRef[ref]; ok {
continue
}
rc.Stop(ctx)
delete(c.refControllers, ref)
logger.Error(nil, "stopped and removed controller for resource", "resource", ref)
return ctrl.Result{Requeue: true}, nil
}
return ctrl.Result{}, nil
}