in internal/controllers/reconciliation/reconstitution.go [112:152]
func (r *reconstitutionSource) populateCache(ctx context.Context, comp *apiv1.Composition, synthesis *apiv1.Synthesis) (bool, error) {
if synthesis == nil || synthesis.Synthesized == nil {
// synthesis is still in progress
return false, nil
}
// The informers cache an abbreviated representation of the resource slices to save memory
// We can use them for status but not for spec
slices := make([]apiv1.ResourceSlice, len(synthesis.ResourceSlices))
for i, ref := range synthesis.ResourceSlices {
slice := apiv1.ResourceSlice{}
slice.Name = ref.Name
slice.Namespace = comp.Namespace
err := r.client.Get(ctx, client.ObjectKeyFromObject(&slice), &slice)
if err != nil {
return false, client.IgnoreNotFound(fmt.Errorf("unable to get resource slice (cached): %w", err))
}
slices[i] = slice
}
compNSN := types.NamespacedName{Namespace: comp.Namespace, Name: comp.Name}
if r.cache.Visit(ctx, comp, synthesis.UUID, slices) {
return false, nil
}
// Get the full resource slices to populate the cache
// But don't use the status since it might be ahead of the informer
for i, ref := range synthesis.ResourceSlices {
slice := apiv1.ResourceSlice{}
slice.Name = ref.Name
slice.Namespace = comp.Namespace
err := r.nonCachedReader.Get(ctx, client.ObjectKeyFromObject(&slice), &slice)
if err != nil {
return false, client.IgnoreNotFound(fmt.Errorf("unable to get resource slice (no cache): %w", err))
}
slices[i] = slice
}
r.cache.Fill(ctx, compNSN, synthesis.UUID, slices)
return true, nil
}