Last active
March 25, 2019 21:23
Revisions
-
grantr revised this gist
Mar 25, 2019 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,6 +50,8 @@ func (crr *ControllerRuntimeReconciler) Start(ctx context.Context) error { // Manager setup is done by a package-level function containing // a sync.Once. mgr, err := GetManager() // The Reconciler object given to controller.Controller is the internal // controllerRuntimeReconcileImpl object rather than this outer one. } // This is an internal type that implements the -
grantr revised this gist
Mar 25, 2019 . 1 changed file with 24 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,12 +25,20 @@ type ObjectFinalizer interface { // interfaces, e.g. BrokerReconciler, BrokerFinalizer that take // *eventingv1alpha1.Broker instead of runtime.Object. // Each Reconciler struct embeds an "implementation" struct. This allows multiple // versions of controller boilerplates to be used concurrently, with as many // interfaces as possible remaining the same. Ideally we would eventually converge // on a single implementation, but that's not guaranteed - they may have different // performance or flexibility tradeoffs. // BrokerReconciler is a Reconciler that embeds the Controller Runtime reconciler // struct to get its behavior. type BrokerReconciler struct { *ControllerRuntimeReconciler } // ControllerRuntimeReconciler is an implementation of all the boilerplate necessary // to write and run a Reconciler that uses Controller Runtime underneath. type ControllerRuntimeReconciler struct { crr controllerRuntimeReconcileImpl } @@ -54,6 +62,19 @@ type controllerRuntimeReconcileImpl struct { func (crri *controllerRuntimeReconcileImpl) Reconcile(request reconcile.Request) (reconcile.Result, error) { } // RevisionReconciler embeds the client-go Reconciler implementation. type RevisionReconciler struct { *ClientGoReconciler } // ClientGoReconciler is an alternative to ControllerRuntimeReconciler. type ClientGoReconciler struct { } // Start implements the client-go boilerplate, e.g. starting informers. func (cgr *ClientGoReconciler) Start(ctx context.Context) { } // Starter is used by the main function to start each reconciler, and blocks // until the controller is stopped. This is implemented by an embedded struct. type Starter interface { @@ -92,8 +113,10 @@ var ( // Reconciler packages define init() methods that set up reconcilers as // package-internal vars, then add those vars to the default starters list. func init() { // The content of this function will be specific to the Reconciler behavior // and the implementation being used. br := &BrokerReconciler{ // The content of this } Starters.Add(br) } -
grantr revised this gist
Mar 25, 2019 . No changes.There are no files selected for viewing
-
grantr created this gist
Mar 25, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,118 @@ // ObjectReconciler is what the user implements. This is the generic version. // The controller MUST be aware of whether it's running with CR or CG. // With this interface, at least the code will be structured similarly // and the client interaction can converge over time (or not, as desired) // This is called ObjectReconciler to avoid confusion with existing Reconciler // interfaces. type ObjectReconciler interface { // This could alternately be called ReconcileObject. Reconcile(context.Context, runtime.Object) error } // ObjectFinalizer is optionally implemented by the user when a finalizer is // required. type ObjectFinalizer interface { // AddFinalizer is called when the object has no finalizer and has not // been deleted. The function can return true or false to signal that // a finalizer should be added or not. Most of the time it will just // return true. AddFinalizer(context.Context, runtime.Object) bool // FinalizeObject is called when the object has a finalizer and has been deleted. Finalize(context.Context, runtime.Object) error } // Code generation could possibly be used to generate typed versions of these // interfaces, e.g. BrokerReconciler, BrokerFinalizer that take // *eventingv1alpha1.Broker instead of runtime.Object. // BrokerReconciler is a Reconciler that embeds the Controller Runtime reconciler // struct to get its behavior. type BrokerReconciler struct { *ControllerRuntimeReconciler } type ControllerRuntimeReconciler struct { crr controllerRuntimeReconcileImpl } // Start implements the Controller Runtime ProvideController boilerplate. // It adds the reconciler to a package-level Manager which is now an // implementation detail of this package. func (crr *ControllerRuntimeReconciler) Start(ctx context.Context) error { // Manager setup is done by a package-level function containing // a sync.Once. mgr, err := GetManager() } // This is an internal type that implements the // Reconcile(reconcile.Request) (reconcile.Result, error) interface that // Controller Runtime expects. Keeping this internal avoids method signature // conflicts and user visibility of the Controller Runtime interface. type controllerRuntimeReconcileImpl struct { } func (crri *controllerRuntimeReconcileImpl) Reconcile(request reconcile.Request) (reconcile.Result, error) { } // Starter is used by the main function to start each reconciler, and blocks // until the controller is stopped. This is implemented by an embedded struct. type Starter interface { Start(context.Context) error } // StarterList collects starters and starts them with an errgroup. type StarterList struct{ starters []Starter } func (sl *StarterList) Add(s Starter) { sl.starters = append(sl.starters, s) } func (sl *StarterList) Items() []Starter { return sl.starters } func (sl *StarterList) Start(ctx context.Context) error { g, gCtx := errgroup.WithContext(ctx) for _, s := range sl.Starters.Items() { g.Go(func() error { return s.Start(gCtx) }) } g.Wait() } // There's a default package-level StartersList in the enclosing package, // similar to scheme.Scheme. var ( Starters StarterList ) // Reconciler packages define init() methods that set up reconcilers as // package-internal vars, then add those vars to the default starters list. func init() { br := &BrokerReconciler{ // ... } Starters.Add(br) } // The controller manager main function looks like this. func main() { // Do logging, config set up tasks as needed signaledCtx, cancel := SignaledContext(configuredCtx) log.Fatalf(Starters.Start(signaledCtx)) } // SignaledContext is a slightly reworking of the existing signals code to use // context cancellation instead of stop channels. func SignaledContext(ctx context.Context) (context.Context, context.CancelFunc) { signaledCtx, cancel := context.WithCancel(ctx) go func() { <-globalSignalsCh cancel() } return signaledCtx, cancel }