Newer
Older
AnthosCertManager / pkg / controller / builder.go
package controller

import (
	"context"
	"fmt"
	"time"

	logf "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/logs"
)

// Builder is used to build controllers that implement the queuingController
// interface
type Builder struct {
	// the root controller context factory. Used to build a component context
	// which is passed when calling Register() on the queueing Controller.
	contextFactory *ContextFactory

	// name is the name for this controller
	name string

	// the actual controller implementation
	impl queueingController

	// runFirstFuncs are a list of functions that will be called immediately
	// after the controller has been initialised, once. They are run in queue, sequentially,
	// and block runDurationFuncs until complete.
	runFirstFuncs []runFunc

	// runPeriodicFuncs are a list of functions that will be called every
	// 'interval'
	runPeriodicFuncs []runPeriodicFunc
}

// New creates a basic Builder, setting the sync call to the one given
func NewBuilder(controllerctx *ContextFactory, name string) *Builder {
	return &Builder{
		contextFactory: controllerctx,
		name:           name,
	}
}

func (b *Builder) For(ctrl queueingController) *Builder {
	b.impl = ctrl
	return b
}

// With will register an additional function that should be called every
// 'interval' alongside the controller.
// This is useful if a controller needs to periodically run a scheduled task.
func (b *Builder) With(function func(context.Context), interval time.Duration) *Builder {
	b.runPeriodicFuncs = append(b.runPeriodicFuncs, runPeriodicFunc{
		fn:       function,
		interval: interval,
	})
	return b
}

// First will register a function that will be called once, after the
// controller has been initialised. They are queued, run sequentially, and
// block "With" runDurationFuncs from running until all are complete.
func (b *Builder) First(function func(context.Context)) *Builder {
	b.runFirstFuncs = append(b.runFirstFuncs, function)
	return b
}

func (b *Builder) Complete() (Interface, error) {
	controllerctx, err := b.contextFactory.Build(b.name)
	if err != nil {
		return nil, err
	}

	ctx := logf.NewContext(controllerctx.RootContext, logf.Log, b.name)

	if b.impl == nil {
		return nil, fmt.Errorf("controller implementation must be non-nil")
	}
	queue, mustSync, err := b.impl.Register(controllerctx)
	if err != nil {
		return nil, fmt.Errorf("error registering controller: %v", err)
	}

	return NewController(ctx, b.name, b.impl.ProcessItem, mustSync, b.runPeriodicFuncs, queue), nil
}