Skip to content

Commit

Permalink
componentsregistry: use structure to store handlers (#1502)
Browse files Browse the repository at this point in the history
To make it possible to mock registry in DSC reconcileComponents for
testing, implement registry as a structure. Make package level
wrappers on Add and ForEach methods which operate on the default
statically created registry.

This allows keep working with the default registry in a real system
without extra arguments like before. It's in init()s and in
main(). But code under test can accept testing version when needed.

Signed-off-by: Yauheni Kaliuta <[email protected]>
  • Loading branch information
ykaliuta authored Jan 15, 2025
1 parent 1960209 commit 8622753
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R
}

// deploy components
if err := r.reconcileComponents(ctx, instance); err != nil {
if err := r.reconcileComponents(ctx, instance, cr.DefaultRegistry()); err != nil {
log.Info(err.Error())
status.SetCondition(&instance.Status.Conditions, "Degraded", status.ReconcileFailed, err.Error(), corev1.ConditionTrue)
}
Expand Down Expand Up @@ -150,13 +150,16 @@ func (r *DataScienceClusterReconciler) validate(ctx context.Context, _ *dscv1.Da
return nil
}

func (r *DataScienceClusterReconciler) reconcileComponents(ctx context.Context, instance *dscv1.DataScienceCluster) error {
func (r *DataScienceClusterReconciler) reconcileComponents(
ctx context.Context,
instance *dscv1.DataScienceCluster,
reg *cr.Registry) error {
log := logf.FromContext(ctx).WithName("DataScienceCluster")

notReadyComponents := make([]string, 0)

// all DSC defined components
componentErrors := cr.ForEach(func(component cr.ComponentHandler) error {
componentErrors := reg.ForEach(func(component cr.ComponentHandler) error {
ci, err := r.reconcileComponent(ctx, instance, component)
if err != nil {
return err
Expand Down
34 changes: 26 additions & 8 deletions pkg/componentsregistry/componentsregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,43 @@ type ComponentHandler interface {
UpdateDSCStatus(dsc *dscv1.DataScienceCluster, obj client.Object) error
}

var registry = []ComponentHandler{}
// Registry is a struct that maintains a list of registered ComponentHandlers.
type Registry struct {
handlers []ComponentHandler
}

var r = &Registry{}

// Add registers a new component handler
// Add registers a new ComponentHandler to the registry.
// not thread safe, supposed to be called during init.
// TODO: check if init() can be called in parallel.
func Add(ch ComponentHandler) {
registry = append(registry, ch)
func (r *Registry) Add(ch ComponentHandler) {
r.handlers = append(r.handlers, ch)
}

// ForEach iterates over all registered component handlers
// ForEach iterates over all registered ComponentHandlers and applies the given function.
// If any handler returns an error, that error is collected and returned at the end.
// With go1.23 probably https://go.dev/blog/range-functions can be used.
func ForEach(f func(ch ComponentHandler) error) error {
func (r *Registry) ForEach(f func(ch ComponentHandler) error) error {
var errs *multierror.Error
for _, ch := range registry {
for _, ch := range r.handlers {
errs = multierror.Append(errs, f(ch))
}

return errs.ErrorOrNil()
}

func Add(ch ComponentHandler) {
r.Add(ch)
}

func ForEach(f func(ch ComponentHandler) error) error {
return r.ForEach(f)
}

func DefaultRegistry() *Registry {
return r
}

func IsManaged(ch ComponentHandler, dsc *dscv1.DataScienceCluster) bool {
return ch.GetManagementState(dsc) == operatorv1.Managed
}

0 comments on commit 8622753

Please sign in to comment.