domain

package
v0.7.9 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

README

domain

domain defines the core interfaces that everything in Orkestra implements against. No business logic lives here — only the contracts that let the runtime, reconciler, gateway, and CLI coordinate without importing each other.

What is here

File What it defines
object.go Object and ObjectList — the minimal Kubernetes object interface used everywhere a resource must be both a metav1.Object and a runtime.Object
domain.go Komponent — the lifecycle interface for anything the manager starts and stops; Reconciler — the single-method contract every CRD reconciler satisfies
health.go Health — the liveness and readiness contract, following Kubernetes probe semantics
generic.go ReconcileHooks[T], AnyReconcileHooks, ObjectHooks, HookBinder — the typed hook system that lets users attach Go functions to a CRD's reconcile and delete events without giving up the declarative layer

Why a separate package

Every Orkestra package that participates in the runtime cycle needs to share these types. Putting them here keeps the import graph acyclic — pkg/reconciler, pkg/webhook, pkg/kordinator, and cmd can all import domain without pulling in each other.

The hook type system

ReconcileHooks[T] is the user-facing API. Users write:

domain.ReconcileHooks[*Database]{
    OnReconcile: func(ctx context.Context, obj *Database) error { ... },
    OnDelete:    func(ctx context.Context, obj *Database) error { ... },
}

Internally, ReconcileHooks[T] is adapted to ObjectHooks via BindToObjectHooks() — a type-erased form that the generic reconciler stores so it can serve both typed (*Database) and dynamic (domain.Object) paths from a single implementation.

See generic.go for the full design rationale in the file header.

Documentation

Overview

domain/generic.go

Hook types for the Orkestra reconcile framework.

There are three layers here, each serving a different audience:

  1. ReconcileHooks[T] — the user-facing API. Users write: domain.ReconcileHooks[*Database]{OnReconcile: myFunc} T is always a concrete pointer type (*Database, *Pipeline, etc.) because Kubernetes informers store and return pointer values.

  2. AnyReconcileHooks — the type-erased marker interface. Allows the Katalog and ObjectRegistry to store hooks without knowing T. The unexported isHooks() method prevents accidental implementation.

  3. ObjectHooks / HookBinder — the internal adapter layer. GenericReconciler stores ObjectHooks, not ReconcileHooks[T], so that a single reconciler type can serve both the typed user-hooks path (T = *Database) and the dynamic template path (T = domain.Object) that goes through the runtime registry in runtime_konstructor.go. See pkg/reconciler/ptr_hooks.go for the full design rationale.

domain/health.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnyReconcileHooks

type AnyReconcileHooks interface {
	// contains filtered or unexported methods
}

AnyReconcileHooks is the type-erased marker interface for ReconcileHooks[T]. It allows the Katalog, ObjectRegistry, and HookFactory closures to store hooks without knowing the concrete T at compile time.

The unexported isHooks() method prevents third-party types from accidentally satisfying this interface; only ReconcileHooks[T] values qualify.

type Health

type Health interface {
	// SetReady marks the component as initialised and ready to process work.
	// Called once by the component after successful startup.
	// Implies the component is also healthy.
	SetReady()

	// Degraded marks the component as alive but not ready to process work.
	// Used when a recoverable error condition is detected — for example,
	// when a CRD's consecutive failure threshold is exceeded.
	// The component remains running but is removed from the ready pool.
	// Distinct from Unhealthy: the process does not need to be restarted.
	Degraded()

	// Unhealthy marks the component as neither healthy nor ready.
	// Called during shutdown or when an unrecoverable error is detected.
	// A Kubernetes liveness probe failing on this state will trigger a restart.
	Unhealthy()

	// Healthy returns true if the component is in a healthy state.
	// Maps to the Kubernetes liveness probe — false triggers a pod restart.
	Healthy() bool

	// Ready returns true if the component is initialised and ready to process work.
	// Maps to the Kubernetes readiness probe — false removes the pod from service endpoints.
	Ready() bool

	// Started returns true if the component has been started at least once.
	// Used by the manager to guard against double-start and to sequence
	// post-start hooks correctly.
	Started() bool
}

Health is the observability contract for any Orkestra Komponent that exposes liveness and readiness state.

Implementations are expected to be safe for concurrent use — all methods may be called from multiple goroutines simultaneously.

The distinction between healthy and ready follows the Kubernetes convention:

  • Healthy (liveness) — the component is alive and not in a broken state. An unhealthy component should be restarted.
  • Ready (readiness) — the component is initialised and able to serve traffic or process work. A non-ready component should not receive work yet but does not need to be restarted.

Typical lifecycle:

NewComponent()  → healthy: false, ready: false
Start()         → healthy: true,  ready: true   (via SetReady + Healthy)
Shutdown()      → healthy: false, ready: false   (via Unhealthy)
Error condition → healthy: false, ready: true    (via Degraded — still alive, not accepting work)

type HookBinder added in v0.2.8

type HookBinder interface {
	AnyReconcileHooks
	// BindToObjectHooks wraps each hook function in a closure that performs
	// a runtime obj.(T) assertion before delegating to the typed function.
	// OnNotFound is forwarded unchanged — it receives a string key, not an object.
	BindToObjectHooks() ObjectHooks
}

HookBinder is satisfied by every ReconcileHooks[T] value. GenericReconciler calls BindToObjectHooks() through this interface at construction time so it can adapt any typed hooks to ObjectHooks without knowing the concrete T.

Third-party hook wrappers that embed or delegate to ReconcileHooks[T] must also implement HookBinder to work with NewGenericReconciler.

type Komponent

type Komponent interface {

	// Start() starts the komponents
	Start(context.Context) error

	// Shutdown() shuts down the komponent gracefully
	Shutdown(context.Context)

	// Name() returns the name of the komponent
	Name() string

	// Started() is set when manager starts a komponent
	Started() bool
}

type Object

type Object interface {
	metav1.Object
	runtime.Object
}

type ObjectHooks added in v0.2.8

type ObjectHooks struct {
	OnReconcile func(ctx context.Context, obj Object) error
	OnDelete    func(ctx context.Context, obj Object) error
	OnNotFound  func(ctx context.Context, key string) error
}

ObjectHooks is the type-erased counterpart to ReconcileHooks[T]. GenericReconciler stores this internally; users never construct it directly. Produce it by calling ReconcileHooks[T].BindToObjectHooks().

type ObjectList

type ObjectList interface {
	metav1.ListInterface
	runtime.Object
}

type ReconcileHooks

type ReconcileHooks[T Object] struct {
	// OnReconcile is called for every create/update event.
	// obj is already type-asserted and deep-copied from the informer cache.
	// Return an error to requeue with backoff.
	OnReconcile func(ctx context.Context, obj T) error

	// OnDelete is called when the object's DeletionTimestamp is set.
	// Use this to clean up external resources before the finalizer is removed.
	// If nil, deletion proceeds with only finalizer removal.
	OnDelete func(ctx context.Context, obj T) error

	// OnNotFound is called when the object no longer exists in the store.
	// Use this for cleanup that depends on the key but not the object itself.
	// If nil, not-found events are a no-op.
	OnNotFound func(ctx context.Context, key string) error
}

ReconcileHooks contains the user-provided business logic for a CRD. Only implement the hooks you need — all fields are optional.

T must be a pointer to the concrete CR type (e.g. *Database). This matches how Kubernetes informers work: they store and return pointers, so type-asserting the informer cache entry to T succeeds only for *T, not T.

Example:

func DatabaseHooks() domain.AnyReconcileHooks {
    return domain.ReconcileHooks[*apiv1.Database]{
        OnReconcile: onDatabaseReconcile,
        OnDelete:    onDatabaseDelete,
    }
}

func (ReconcileHooks[T]) BindToObjectHooks added in v0.2.8

func (h ReconcileHooks[T]) BindToObjectHooks() ObjectHooks

BindToObjectHooks implements HookBinder for ReconcileHooks[T]. The returned ObjectHooks closures assert obj to T on every call. This is safe because the informer guarantees every object in its cache is of the type it was built for.

type Reconciler

type Reconciler interface {
	// Reconcile handles the actual business logic for a resource
	Reconcile(ctx context.Context, key string) error
}

Jump to

Keyboard shortcuts

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