entdefine

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package entdefine is the defining side of the Temporal Entity Lifecycle Pattern chassis (aka Entity Workflow): one long-running workflow per resource, acting as the durable control-plane record for it. Users declare typed command and query descriptors and register handlers containing ordinary Temporal code (activities, child workflows, timers); the chassis owns everything the pattern requires — the serialized command queue and main loop, update validators, request-id deduplication, Continue-as-New, deletion as a lifecycle transition, periodic reconcile ticks, queries, and search attributes.

Index

Constants

This section is empty.

Variables

View Source
var (
	SearchAttrKind  = temporal.NewSearchAttributeKeyKeyword("EntityKind")
	SearchAttrPhase = temporal.NewSearchAttributeKeyKeyword("EntityPhase")
	// SearchAttrLabels mirrors the entity's labels as "k=v" keywords, so
	// visibility queries can select by label: EntityLabels IN ("env=prod").
	SearchAttrLabels = temporal.NewSearchAttributeKeyKeywordList("EntityLabels")
)

Search attribute keys (article: "use resource-oriented Workflow IDs and Search Attributes for queryability"). Registered on the cluster by run.sh.

Functions

func HandleQuery

func HandleQuery[Spec, State, Res any, Req entity.Query[Res]](
	d *Definition[Spec, State],
	fn func(s entity.Snapshot[Spec, State], req Req) (Res, error),
)

HandleQuery registers a query handler; the query is the request type itself (implementing entity.Query[Res]). Query handlers see a read-only Snapshot and MUST be pure: no side effects, no workflow APIs, no blocking — Temporal query semantics.

Types

type CommandRegistration

type CommandRegistration[Spec, State, Req any] struct {
	// contains filtered or unexported fields
}

CommandRegistration is the fluent tail of Handle, for attaching a kind-level validator (one that needs registration-time dependencies a command type's own Validate method cannot capture — e.g. k8slib's per-kind validation config).

func Handle

func Handle[Spec, State, Res any, Req entity.Command[Res]](
	d *Definition[Spec, State],
	fn func(ctx workflow.Context, ec *Ctx[Spec, State], req Req) (Res, error),
) *CommandRegistration[Spec, State, Req]

Handle registers a command handler. The command is the REQUEST TYPE itself (implementing entity.Command[Res]): its name, parameters, response type, and optional Validate method all live on that one type, and everything is inferred from the handler's signature — no descriptors, no strings. Handlers run on the entity's main loop — never concurrently with another command — and contain ordinary Temporal code.

func (*CommandRegistration[Spec, State, Req]) Validate

func (r *CommandRegistration[Spec, State, Req]) Validate(fn func(s entity.Snapshot[Spec, State], req Req) error) *CommandRegistration[Spec, State, Req]

Validate attaches a kind-level update validator. It runs in addition to the command type's own Validate method (if any); both see a read-only Snapshot and must be pure and deterministic.

type Ctx

type Ctx[Spec, State any] struct {
	// contains filtered or unexported fields
}

Ctx is what command/reconcile handlers get: access to the entity's desired Spec and current State. Handlers run on the main loop, so all mutations are serialized by construction.

func (*Ctx[Spec, State]) Labels

func (c *Ctx[Spec, State]) Labels() map[string]string

Labels returns a copy of the entity's labels.

func (*Ctx[Spec, State]) Phase

func (c *Ctx[Spec, State]) Phase() entity.Phase

Phase returns the entity lifecycle phase.

func (*Ctx[Spec, State]) SetLabel

func (c *Ctx[Spec, State]) SetLabel(key, value string)

SetLabel sets (or, with an empty value, removes) one label from a command/reconcile handler. The search-attribute mirror follows on the main loop.

func (*Ctx[Spec, State]) SetSpec

func (c *Ctx[Spec, State]) SetSpec(s Spec)

SetSpec replaces the desired spec.

func (*Ctx[Spec, State]) Spec

func (c *Ctx[Spec, State]) Spec() Spec

Spec returns the current desired spec.

func (*Ctx[Spec, State]) State

func (c *Ctx[Spec, State]) State() *State

State returns the mutable user state.

type Definition

type Definition[Spec, State any] struct {
	// contains filtered or unexported fields
}

Definition describes one entity kind: its lifecycle handlers plus the registry of declared commands and queries. Mutable only during registration (composition root); frozen once Register is called. Registration problems accumulate as an error list and fail Register — they never panic (the protobuf-go registration lesson).

func New

func New[Spec, State any](kind entity.KindName, opts ...Option[Spec, State]) *Definition[Spec, State]

New declares an entity kind.

func (*Definition[Spec, State]) Commands

func (d *Definition[Spec, State]) Commands() []entity.CommandInfo

Commands enumerates the registered commands — introspection for a future manifest.

func (*Definition[Spec, State]) Kind

func (d *Definition[Spec, State]) Kind() entity.KindName

Kind returns the entity kind name.

func (*Definition[Spec, State]) Queries

func (d *Definition[Spec, State]) Queries() []entity.QueryInfo

Queries enumerates the registered queries.

func (*Definition[Spec, State]) Register

func (d *Definition[Spec, State]) Register(w worker.WorkflowRegistry) error

Register attaches the entity workflow to a worker. All accumulated registration errors surface here as one list.

type Option

type Option[Spec, State any] func(*Definition[Spec, State])

Option configures a Definition at declaration time.

func WithFinalize

func WithFinalize[Spec, State any](fn func(ctx workflow.Context, state *State) error) Option[Spec, State]

WithFinalize sets the deletion handler, run after the entity is marked for deletion and its queue is drained.

func WithForceCANEveryNCommands

func WithForceCANEveryNCommands[Spec, State any](n int) Option[Spec, State]

WithForceCANEveryNCommands is test-only; see forceCANEvery.

func WithInit

func WithInit[Spec, State any](fn func(ctx workflow.Context, spec Spec) (State, error)) Option[Spec, State]

WithInit sets the creation handler: bring the resource to life from its desired Spec (ordinary Temporal code inside).

func WithReconcileEvery

func WithReconcileEvery[Spec, State any](every time.Duration, fn func(ctx workflow.Context, ec *Ctx[Spec, State]) error) Option[Spec, State]

WithReconcileEvery installs the periodic health/drift tick: when the main loop's wait times out (article: timer expiration in the main loop), fn runs — serialized with commands like everything else.

func WithSearchAttributes

func WithSearchAttributes[Spec, State any](on bool) Option[Spec, State]

WithSearchAttributes toggles upserting EntityKind/EntityPhase typed search attributes (they must exist on the cluster).

type Saga

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

Saga implements the article's compensation pattern for multi-step operations inside a command handler: execute steps forward tracking the completed ones; on failure, run their compensations in reverse order. Run returns the original error instead of failing the whole workflow, so the entity keeps living and the command's caller sees the failure. Both forward and compensating actions must be idempotent — they run as activities and can be retried.

func NewSaga

func NewSaga(ctx workflow.Context) *Saga

NewSaga starts an empty saga bound to the workflow context.

func (*Saga) Run

func (s *Saga) Run() error

Run executes all steps in order. On the first failure it compensates the already-completed steps in reverse order and returns the step's error (with any compensation errors joined in — compensation failures must be visible, not swallowed).

func (*Saga) Step

func (s *Saga) Step(name string, forward, compensate func(ctx workflow.Context) error) *Saga

Step adds a forward action with its compensation. compensate may be nil for steps that need no undo.

Jump to

Keyboard shortcuts

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