subroutines

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

README

Platform Mesh - subroutines

CI Go Reference License

Description

subroutines is a lifecycle engine for Kubernetes controllers built on multicluster-runtime. It offers explicit Result-based flow control, opt-in condition/status management, and built-in observability.

  • Subroutine orchestration — chain subroutines with typed Result values (OK, Pending, Stop) instead of plain errors
  • Condition management — automatic per-subroutine and aggregate Ready conditions
  • Spread scheduling — distribute reconciliation load over configurable time windows to avoid thundering-herd effects
  • Finalizer lifecycle — declarative finalizer registration, ordered teardown, and initializer/terminator support
  • Observability — built-in Prometheus metrics (duration, errors, requeue) and OpenTelemetry tracing

Getting started

Add the dependency to your Go module:

go get github.com/platform-mesh/subroutines
Quick start
import (
    "github.com/platform-mesh/subroutines/conditions"
    "github.com/platform-mesh/subroutines/lifecycle"
)

lc := lifecycle.New(mgr, "MyController", func() client.Object { return &v1alpha1.MyResource{} },
    subroutine1,
    subroutine2,
).WithConditions(conditions.NewManager())

Each subroutine implements one or more of the core interfaces:

// Processor handles the main reconciliation logic.
type Processor interface {
    Subroutine
    Process(ctx context.Context, obj client.Object) (Result, error)
}

// Finalizer handles cleanup when an object is being deleted.
type Finalizer interface {
    Subroutine
    Finalize(ctx context.Context, obj client.Object) (Result, error)
    Finalizers(obj client.Object) []string
}

Subroutines return a Result to control the chain:

subroutines.OK()                          // continue, no requeue
subroutines.OKWithRequeue(5 * time.Minute) // continue, requeue after duration
subroutines.Pending(30 * time.Second, "waiting for dependency") // continue, set condition to Unknown
subroutines.StopWithRequeue(time.Minute, "rate limited")        // stop chain, requeue
subroutines.Stop("done")                                        // stop chain, no requeue

Packages

Package Description
subroutines Core interfaces (Subroutine, Processor, Finalizer, Initializer, Terminator) and Result type
lifecycle Orchestration engine — executes subroutines, manages finalizers, patches status
conditions Per-subroutine and aggregate Ready condition management
spread Reconciliation spreading to distribute load over time
metrics Prometheus metrics for subroutine execution

Requirements

subroutines requires Go. Check the go.mod for the required Go version.

Contributing

Please refer to the CONTRIBUTING.md file in this repository for instructions on how to contribute to Platform Mesh.

Code of Conduct

Please refer to our Code of Conduct for information on the expected conduct for contributing to Platform Mesh.

Bundesministerium für Wirtschaft und Energie (BMWE)-EU funding logo

Documentation

Overview

Package subroutines provides a lifecycle engine for Kubernetes controllers built on multicluster-runtime. It offers explicit Result-based flow control, opt-in condition/status/finalizer management, and built-in observability.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClientFromContext

func ClientFromContext(ctx context.Context) (client.Client, error)

ClientFromContext retrieves the client.Client from the context.

func MustClientFromContext

func MustClientFromContext(ctx context.Context) client.Client

MustClientFromContext retrieves the client.Client from the context. It panics if no client is stored in the context.

func WithClient

func WithClient(ctx context.Context, cl client.Client) context.Context

WithClient stores a client.Client in the context.

Types

type Finalizer

type Finalizer interface {
	Subroutine
	Finalize(ctx context.Context, obj client.Object) (Result, error)
	Finalizers(obj client.Object) []string
}

Finalizer handles cleanup when an object is being deleted.

type Initializer

type Initializer interface {
	Subroutine
	Initialize(ctx context.Context, obj client.Object) (Result, error)
}

Initializer handles one-time initialization when an initializer marker is present in status.

type Processor

type Processor interface {
	Subroutine
	Process(ctx context.Context, obj client.Object) (Result, error)
}

Processor handles the main reconciliation logic for a subroutine.

type Result

type Result struct {
	// contains filtered or unexported fields
}

Result encodes the outcome of a subroutine invocation. The zero value represents a successful continue with no requeue.

func OK

func OK() Result

OK returns a Result that continues the chain with no requeue.

func OKWithRequeue

func OKWithRequeue(d time.Duration) Result

OKWithRequeue returns a Result that continues the chain and requeues after d.

func Pending

func Pending(d time.Duration, msg string) Result

Pending returns a Result that continues the chain, sets the condition to Unknown, and requeues after d. Use Pending when a subroutine is waiting on an external condition. Note: the lifecycle engine picks the shortest requeue across all subroutines, so a later subroutine returning OKWithRequeue with a shorter duration will take precedence. Panics if d <= 0.

func SkipAll

func SkipAll(ready bool, msg string) Result

SkipAll halts the subroutine chain and marks remaining subroutines as Skipped. The ready flag controls the aggregate Ready condition: true sets it to True, false sets it to False.

func Stop

func Stop(msg string) Result

Stop returns a Result that stops the chain with no explicit requeue.

func StopWithRequeue

func StopWithRequeue(d time.Duration, msg string) Result

StopWithRequeue returns a Result that stops the chain and requeues after d.

func (Result) IsContinue

func (r Result) IsContinue() bool

IsContinue returns true if the result is OK or OKWithRequeue. Note: Pending also continues the chain but returns false here — use IsPending to check for that case separately.

func (Result) IsPending

func (r Result) IsPending() bool

IsPending returns true if the result is Pending.

func (Result) IsSkipAll

func (r Result) IsSkipAll() bool

IsSkipAll returns true if the result halts the chain and marks remaining subroutines as Skipped.

func (Result) IsStop

func (r Result) IsStop() bool

IsStop returns true if the result stops the chain with no requeue.

func (Result) IsStopWithRequeue

func (r Result) IsStopWithRequeue() bool

IsStopWithRequeue returns true if the result stops the chain with a requeue.

func (Result) Message

func (r Result) Message() string

Message returns the result message.

func (Result) Ready

func (r Result) Ready() bool

Ready returns the ready flag, which controls the aggregate Ready condition for SkipAll results.

func (Result) Requeue

func (r Result) Requeue() time.Duration

Requeue returns the requeue duration.

type Subroutine

type Subroutine interface {
	GetName() string
}

Subroutine is the base interface that all subroutines must implement.

type Terminator

type Terminator interface {
	Subroutine
	Terminate(ctx context.Context, obj client.Object) (Result, error)
}

Terminator handles ordered teardown when a terminator marker is present in status.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL