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 ¶
- Variables
- func HandleQuery[Spec, State, Res any, Req entity.Query[Res]](d *Definition[Spec, State], ...)
- type CommandRegistration
- type Ctx
- type Definition
- type Option
- func WithFinalize[Spec, State any](fn func(ctx workflow.Context, state *State) error) Option[Spec, State]
- func WithForceCANEveryNCommands[Spec, State any](n int) Option[Spec, State]
- func WithInit[Spec, State any](fn func(ctx workflow.Context, spec Spec) (State, error)) Option[Spec, State]
- func WithReconcileEvery[Spec, State any](every time.Duration, fn func(ctx workflow.Context, ec *Ctx[Spec, State]) error) Option[Spec, State]
- func WithSearchAttributes[Spec, State any](on bool) Option[Spec, State]
- type Saga
Constants ¶
This section is empty.
Variables ¶
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]) SetLabel ¶
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.
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 ¶
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 ¶
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.