Documentation
¶
Overview ¶
Package tasks defines the engine's external-worker execution contract: an asynchronous fetch-and-lock job queue (ADR-021 §2.4, SRD-036). The engine Enqueues a job and parks the ServiceTask; a worker FetchAndLocks it, executes, and reports (Complete/Fail); the report re-enters the instance loop as a WorkerOutcome and resumes the parked track. The in-process default lives in the localdispatcher sibling subpackage; a remote adapter (HTTP/gRPC) is a future extension (ADR-004).
Index ¶
- func ApplyOutputMapping(ctx context.Context, ee expression.Engine, rules []OutputRule, ...) ([]data.Data, error)
- type BpmnError
- type ErrorMapper
- type ExpressionEngineBinder
- type ExternalWorker
- type Fault
- type Job
- type JobCompletionSink
- type JobID
- type LockedJob
- type LoggerBinder
- type MappedOutcome
- type OutcomeKind
- type OutputRule
- type Policy
- type ReporterBinder
- type RetryPolicy
- type Rule
- type RuleMapper
- type SinkBinder
- type Status
- type Technical
- type Topic
- type TrustMode
- type WorkerConfig
- type WorkerDispatcher
- type WorkerError
- type WorkerID
- type WorkerOutcome
- func (o *WorkerOutcome) BpmnError() (code, message string)
- func (o *WorkerOutcome) Fault() Fault
- func (o *WorkerOutcome) GetItemsList() []*data.ItemDefinition
- func (o *WorkerOutcome) JobID() JobID
- func (o *WorkerOutcome) Kind() OutcomeKind
- func (o *WorkerOutcome) Output() []data.Data
- func (o *WorkerOutcome) StatusValue() data.Value
- func (o *WorkerOutcome) Type() flow.EventTrigger
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyOutputMapping ¶ added in v0.9.0
func ApplyOutputMapping( ctx context.Context, ee expression.Engine, rules []OutputRule, body *data.ItemDefinition, ) ([]data.Data, error)
ApplyOutputMapping evaluates each rule's Path over body and returns the extracted data to commit as the ServiceTask's output, one datum per Var head. A plain Var ("orderId") emits its evaluated value whole; a set of structural Vars sharing a head ("order.total", "order.items[0].price") assembles ONE record for that head via values.SetPath (ADR-011 v.6 §2.9.3, §2.9.5). Mixing a whole-value and a structural rule on one head, or a malformed Var path, is a classified mapping error; a required path that fails to evaluate is a fault (a worker response that violates the contract → technical fault), an optional one is skipped. The body is exposed to Path as the "body" datum through the same transient Source the ErrorMapper classifier uses (SRD-037 §4.5).
Types ¶
type BpmnError ¶ added in v0.9.0
BpmnError yields a Business Error: the engine raises Code as a BPMN error (interrupting), caught by a matching Error boundary event (ADR-018). Message is an optional diagnostic.
type ErrorMapper ¶ added in v0.9.0
type ErrorMapper interface {
Classify(ctx context.Context, ee expression.Engine, f Fault) (MappedOutcome, error)
}
ErrorMapper classifies a raw worker Fault into a MappedOutcome. The declarative RuleMapper covers the common cases; a custom implementation covers imperative ones the rule list can't express (ADR-021 §2.6). It is evaluated at resume with the execution's expression engine (SRD-037 §4.1).
type ExpressionEngineBinder ¶ added in v0.9.0
type ExpressionEngineBinder interface {
BindExpressionEngine(ee expression.Engine)
}
ExpressionEngineBinder is an optional dispatcher capability: the engine binds its expression engine at startup so the dispatcher can run a Job's ErrorMapper (which evaluates FormalExpressions) when it classifies a raw fault engine-side under EngineAuthoritative (SRD-038). A dispatcher that never classifies engine-side (e.g. a WorkerTrusted-only remote adapter) need not implement it.
type ExternalWorker ¶ added in v0.9.0
type ExternalWorker interface {
// WorkerTopic reports the external-worker topic and whether the node is
// worker-dispatched.
WorkerTopic() (topic Topic, ok bool)
// BindJobInput binds the node's operation input message from r (without
// executing it) — the payload the engine puts in the enqueued Job.Input.
BindJobInput(
ctx context.Context, r service.DataReader,
) (*data.ItemDefinition, error)
}
ExternalWorker is implemented by a node whose work is dispatched to an external worker rather than run in-process. The instance loop diverts a node whose WorkerTopic reports ok == true to the wait-node park path (it enqueues a job and resumes on the worker's report); ok == false runs the node in-process as usual.
type Fault ¶ added in v0.9.0
type Fault struct {
Body *data.ItemDefinition
Cause error
Code string
}
Fault is a worker's raw (unclassified) terminal fault (ADR-021 §2.6, SRD-037). Code is a protocol/domain status (an HTTP status once a remote transport exists, ADR-004); Body is the response payload; Cause is the diagnostic Go error. The engine ErrorMapper classifies {Code, Body}; an all-empty Fault (only Cause) matches no rule and falls through to the default technical outcome.
type Job ¶
type Job struct {
Input *data.ItemDefinition
Policy *Policy
ID JobID
Topic Topic
}
Job is the unit the engine Enqueues. Input is the single bound input-message item (nil if the operation has no inMessage), per the operation contract.
type JobCompletionSink ¶ added in v0.9.0
type JobCompletionSink interface {
ReportJobCompletion(ctx context.Context, outcome *WorkerOutcome) error
}
JobCompletionSink routes a worker's terminal report to the owning instance. The engine implements it; a dispatcher calls it from Complete/Fail. Keeping this separate from WorkerDispatcher keeps the queue decoupled from instance internals (SRD-036 §4.1).
type JobID ¶ added in v0.9.0
type JobID string
JobID identifies one execution of a worker-dispatched ServiceTask; a worker treats it as an idempotency key. It embeds the owning instance's id (see MakeJobID) so a completion routes back to that instance without a separate registry (SRD-036 §4.5).
func MakeJobID ¶ added in v0.9.0
MakeJobID composes a JobID for a worker-dispatched ServiceTask on instanceID, embedding that id so ReportJobCompletion routes the outcome back to the owning instance without a registry (SRD-036 §4.5). The suffix is a fresh unique id, so two jobs on the same instance never collide.
func (JobID) InstanceID ¶ added in v0.9.0
InstanceID returns the owning instance id embedded in the JobID (the segment before the first separator), or the whole string if it carries none.
type LockedJob ¶ added in v0.9.0
LockedJob is a Job a worker received from FetchAndLock, together with its lock: WorkerID holds it until Deadline, extendable via ExtendLock.
type LoggerBinder ¶ added in v0.9.0
type LoggerBinder interface {
BindLogger(logger observability.Logger)
}
LoggerBinder is an optional dispatcher capability: the engine binds its configured logger (from the runtime config) at startup, so a dispatcher's own lifecycle logging uses the embedder's logger rather than a private default. A dispatcher that manages its own logging need not implement it.
type MappedOutcome ¶ added in v0.9.0
type MappedOutcome interface {
// contains filtered or unexported methods
}
MappedOutcome is the classification an ErrorMapper yields for a raw fault: one of BpmnError (business, interrupting), Status (business, non-interrupting), or Technical (retry/terminal). It is a sealed interface — an unexported marker, mirroring options.Option — so the set of outcomes is closed to this package.
type OutcomeKind ¶ added in v0.9.0
type OutcomeKind uint8
OutcomeKind classifies a WorkerOutcome into one of the four ADR-021 §2.6 kinds. The parked ServiceTask dispatches on it at resume (SRD-037 §3.5).
const ( // OutcomeComplete is a success — bind Output, complete. OutcomeComplete OutcomeKind = iota // OutcomeBpmnError is a worker-declared Business Error — raise BpmnCode, caught // by an Error boundary (interrupting). OutcomeBpmnError // OutcomeStatus is a worker-declared Business Status — write StatusValue to the // WithStatus variable, complete normally. OutcomeStatus // OutcomeFault is a raw fault — the engine ErrorMapper classifies Fault{code,body} // at resume. OutcomeFault )
func (OutcomeKind) String ¶ added in v0.9.0
func (k OutcomeKind) String() string
String returns the outcome-kind name for logging.
type OutputRule ¶ added in v0.9.0
type OutputRule struct {
Path data.FormalExpression
Var string
Required bool
}
OutputRule extracts a value from a Complete's raw response body into a named output variable (ADR-021 §2.5, SRD-037 FR-7). Path is a body-path expression (in-process binding: gobpm expressions over Go values, reading the body as the "body" datum); Var is the output variable it fills — a plain name ("orderId") or a structural path ("order.items[0].price", ADR-011 v.6 §2.9.3) that shapes one nested output value; Required makes a path the body doesn't satisfy a fault rather than a skipped mapping.
type Policy ¶ added in v0.9.0
type Policy struct {
// ErrorMapper classifies a raw fault; nil = raw faults fall through to the
// default Technical outcome.
ErrorMapper ErrorMapper
// RetryPolicy drives technical-fault retries; wired in SRD-038 M7 (nil when
// unset).
RetryPolicy RetryPolicy
// OutputMapping shapes a completion's raw body into the final committed output;
// applied by the policy owner (dispatcher/worker), not the track (SRD-039 M8).
// Empty = the raw output is committed directly.
OutputMapping []OutputRule
// Trust selects the policy locus — the worker (WorkerTrusted) or the engine's
// dispatcher (EngineAuthoritative). Resolved at enqueue; never trustUnset on a
// shipped job (SRD-039 M9).
Trust TrustMode
}
Policy is a worker-dispatched ServiceTask's resolved outcome policy. Under EngineAuthoritative (SRD-038) the dispatcher uses it to classify a raw fault (ErrorMapper) and drive technical retries (RetryPolicy); under WorkerTrusted (SRD-039) it is shipped to the worker. The instance resolves it (two-level: per-service over engine-wide) at enqueue. A nil Policy = an in-process task or a not-yet-populated job.
type ReporterBinder ¶ added in v0.9.0
type ReporterBinder interface {
BindReporter(sink observability.Reporter)
}
ReporterBinder is an optional dispatcher capability: the engine binds its observable-event sink (ADR-013 v.2 §2.7) at startup so the dispatcher can emit JobState events (enqueue/lock/report/retry/exhaust/reclaim) onto the one engine-wide seam. A third-party dispatcher that does not implement it simply does not emit — the optional-capability pattern.
type RetryPolicy ¶ added in v0.9.0
RetryPolicy decides whether a technical fault is retried and the backoff before the next attempt (ADR-021 §2.7). attempt is the 1-based number of the attempt that just failed; cause is its technical error.
func DefaultRetryPolicy ¶ added in v0.9.0
func DefaultRetryPolicy() RetryPolicy
DefaultRetryPolicy is the engine default when neither a per-service nor an engine-wide RetryPolicy is set: 3 attempts with jittered exponential backoff from 500ms capped at 30s — improving on Camunda's zero-wait default (ADR-021 §2.7).
func ExponentialBackoff ¶ added in v0.9.0
func ExponentialBackoff( maxAttempts int, base, maxBackoff time.Duration, jitter bool, ) RetryPolicy
ExponentialBackoff returns a RetryPolicy that retries until maxAttempts executions have run, doubling the backoff (base, 2·base, 4·base, …) capped at maxBackoff. With jitter, each backoff is randomized into [d/2, d] to spread retries.
func FixedDelay ¶ added in v0.9.0
func FixedDelay(maxAttempts int, delay time.Duration) RetryPolicy
FixedDelay returns a RetryPolicy that retries a technical fault until maxAttempts executions have been made, waiting delay before each retry.
func NoRetry ¶ added in v0.9.0
func NoRetry() RetryPolicy
NoRetry returns a RetryPolicy that never retries: a technical fault is terminal on first report (a fail-fast worker).
type Rule ¶ added in v0.9.0
type Rule struct {
BodyClause data.FormalExpression
Yield MappedOutcome
Code string
}
Rule is one ErrorMapper classification rule (first match wins). Code is an exact code match ("" matches any code); BodyClause is an optional predicate over the fault's {code, body} (nil = code-only); Yield is the outcome on a match.
type RuleMapper ¶ added in v0.9.0
type RuleMapper struct {
// contains filtered or unexported fields
}
RuleMapper is the declarative ErrorMapper: an ordered rule list, first match wins, falling through to Technical when none match.
func NewRuleMapper ¶ added in v0.9.0
func NewRuleMapper(rules ...Rule) (*RuleMapper, error)
NewRuleMapper builds a declarative ErrorMapper from rules (evaluated in order). A rule with a nil Yield is rejected — every rule must classify to some outcome.
func (*RuleMapper) Classify ¶ added in v0.9.0
func (m *RuleMapper) Classify( ctx context.Context, ee expression.Engine, f Fault, ) (MappedOutcome, error)
Classify returns the first rule's Yield whose code matches and whose BodyClause (if any) evaluates true over the fault's {code, body}; no match → Technical.
type SinkBinder ¶ added in v0.9.0
type SinkBinder interface {
BindSink(sink JobCompletionSink)
}
SinkBinder is an optional dispatcher capability: the engine binds its completion sink at startup so the dispatcher can deliver outcomes back. A dispatcher that reaches the engine another way (e.g. a remote adapter) need not implement it.
type Status ¶ added in v0.9.0
Status yields a Business Status: the engine writes Value to the ServiceTask's WithStatus variable and the task completes normally.
type Technical ¶ added in v0.9.0
type Technical struct{}
Technical yields a technical fault: it feeds the retry policy (SRD-038) and is terminal for now (SRD-037). It is also the implicit default when no rule matches.
type Topic ¶ added in v0.9.0
type Topic string
Topic is a job's type/fetch key — a worker fetches by topic, and it equals a ServiceTask's WithWorker topic.
type TrustMode ¶ added in v0.9.0
type TrustMode uint8
TrustMode governs where a worker-dispatched ServiceTask's policy bundle (output mapping, classification, retry) executes (ADR-021 §2.6). The zero value is "unset" — an internal resolution sentinel; a resolved job is always one of the two exported modes, defaulting to WorkerTrusted.
const ( // WorkerTrusted (default) ships the policy to the worker, which maps its // output, self-classifies its faults, and retries technical faults // internally, reporting only a final verdict (ADR-021 §2.6). WorkerTrusted TrustMode // EngineAuthoritative keeps the policy engine-side: the worker returns the raw // {code, body} and the engine maps / classifies / retries (ADR-021 §2.6). EngineAuthoritative )
func (TrustMode) Resolve ¶ added in v0.9.0
Resolve returns m when it is a configured mode, else fallback. It composes the two-level resolution — per-service over engine-wide over the WorkerTrusted default — while keeping the unset sentinel unexported:
perService.Resolve(engineWide.Resolve(WorkerTrusted))
type WorkerConfig ¶ added in v0.9.0
WorkerConfig is implemented by a node whose worker outcome the engine classifies, maps, and retries. WorkerConfig returns the node's per-service policy (a partial Policy — a nil/empty field means "fall back to the engine-wide default" resolved at enqueue); ok == false for an in-process (non-worker) node.
type WorkerDispatcher ¶
type WorkerDispatcher interface {
// Enqueue adds a job to the queue (non-blocking); the engine then parks the
// ServiceTask.
Enqueue(ctx context.Context, job Job) error
// FetchAndLock returns and locks (for lockDuration, to workerID) the next
// available jobs for the given topics, blocking until at least one is
// available or ctx is done.
FetchAndLock(
ctx context.Context,
workerID WorkerID,
topics []Topic,
lockDuration time.Duration,
) ([]LockedJob, error)
// ExtendLock extends the lock on jobID (held by workerID) by newDuration
// from now. Holder-only; bounded by the configured maxLockDuration.
ExtendLock(
ctx context.Context,
jobID JobID,
workerID WorkerID,
newDuration time.Duration,
) error
// Complete reports a successful outcome: output is the operation's result
// item (nil if the operation has no outMessage).
Complete(
ctx context.Context,
jobID JobID,
workerID WorkerID,
output *data.ItemDefinition,
) error
// ReportBpmnError reports a worker-declared Business Error (Camunda
// handleBpmnError): the engine raises code (message is an optional
// diagnostic), caught by a matching Error boundary event (interrupting).
ReportBpmnError(
ctx context.Context,
jobID JobID,
workerID WorkerID,
code, message string,
) error
// ReportStatus reports a worker-declared Business Status: the engine writes
// value to the ServiceTask's WithStatus variable and the task completes.
ReportStatus(
ctx context.Context,
jobID JobID,
workerID WorkerID,
value data.Value,
) error
// Fail reports a raw fault the engine ErrorMapper classifies (§2.6). A
// pure-technical fault carries only Fault.Cause (empty code, nil body) and
// falls through to the default technical outcome.
Fail(ctx context.Context, jobID JobID, workerID WorkerID, fault Fault) error
}
WorkerDispatcher is an asynchronous fetch-and-lock job queue (ADR-021 §2.4). Enqueue is engine-facing; FetchAndLock / ExtendLock and the four terminal reports (Complete / ReportBpmnError / ReportStatus / Fail) are worker-facing. The reports mirror the four outcome kinds (SRD-037 §2.6): a worker either self-classifies (ReportBpmnError / ReportStatus) or reports a raw Fault the engine ErrorMapper classifies.
type WorkerError ¶ added in v0.9.0
type WorkerError struct {
Cause error // the technical cause (a plain-technical verdict)
Status data.Value // non-nil → a Business Status verdict
BpmnErrorCode string // non-empty → a Business Error verdict
Message string // optional Business Error diagnostic
}
WorkerError is a WorkerFunc's rich, self-classifying error (ADR-021 §2.6): a WorkerTrusted worker returns it to declare its own outcome. Precedence is BpmnErrorCode → Status → technical (Cause). A plain (non-*WorkerError) error is an unclassified technical fault the worker runs through the fallback ErrorMapper.
func (*WorkerError) Error ¶ added in v0.9.0
func (e *WorkerError) Error() string
Error implements error, reporting the declared classification.
type WorkerID ¶ added in v0.9.0
type WorkerID string
WorkerID identifies the worker holding a job's lock.
type WorkerOutcome ¶ added in v0.9.0
type WorkerOutcome struct {
foundation.BaseElement
// contains filtered or unexported fields
}
WorkerOutcome is the synthetic event a worker's report rides back into the instance loop: it implements flow.EventDefinition, so it flows through the parked track's event channel exactly like a UserTask completion (ADR-021 §2.4, SRD-036 §3.2). Its Kind selects which field is meaningful. It never reaches the EventHub or correlation, so its Type is an internal sentinel and it exposes no ItemDefinitions.
func NewWorkerBpmnError ¶ added in v0.9.0
func NewWorkerBpmnError(jobID JobID, code, message string) *WorkerOutcome
NewWorkerBpmnError builds a worker-declared Business Error outcome: the engine raises code (message is an optional diagnostic), caught by an Error boundary.
func NewWorkerComplete ¶ added in v0.9.0
func NewWorkerComplete(jobID JobID, output []data.Data) *WorkerOutcome
NewWorkerComplete builds a successful outcome for job jobID carrying the final committed output (nil if the operation produced none). The output is already shaped — the policy owner (the dispatcher under EngineAuthoritative, the worker under WorkerTrusted) applied WithOutputMapping before this outcome is built, so the track only commits it (SRD-039 §3.4).
func NewWorkerFault ¶ added in v0.9.0
func NewWorkerFault(jobID JobID, fault Fault) *WorkerOutcome
NewWorkerFault builds a raw-fault outcome for job jobID; the engine ErrorMapper classifies fault's {code, body} at resume.
func NewWorkerStatus ¶ added in v0.9.0
func NewWorkerStatus(jobID JobID, value data.Value) *WorkerOutcome
NewWorkerStatus builds a worker-declared Business Status outcome carrying value (written to the ServiceTask's WithStatus variable).
func (*WorkerOutcome) BpmnError ¶ added in v0.9.0
func (o *WorkerOutcome) BpmnError() (code, message string)
BpmnError returns the worker-declared business-error code and message (empty on other kinds).
func (*WorkerOutcome) Fault ¶ added in v0.9.0
func (o *WorkerOutcome) Fault() Fault
Fault returns the raw fault (zero on other kinds); the engine ErrorMapper classifies its {code, body}.
func (*WorkerOutcome) GetItemsList ¶ added in v0.9.0
func (o *WorkerOutcome) GetItemsList() []*data.ItemDefinition
GetItemsList returns nil — a WorkerOutcome carries its data via its kind-specific accessors, not ItemDefinitions.
func (*WorkerOutcome) JobID ¶ added in v0.9.0
func (o *WorkerOutcome) JobID() JobID
JobID returns the job this outcome reports.
func (*WorkerOutcome) Kind ¶ added in v0.9.0
func (o *WorkerOutcome) Kind() OutcomeKind
Kind returns the outcome's classification.
func (*WorkerOutcome) Output ¶ added in v0.9.0
func (o *WorkerOutcome) Output() []data.Data
Output returns the final committed output on a completion — already shaped by the policy owner (nil otherwise). The track commits it as-is.
func (*WorkerOutcome) StatusValue ¶ added in v0.9.0
func (o *WorkerOutcome) StatusValue() data.Value
StatusValue returns the worker-declared business-status value (nil on other kinds).
func (*WorkerOutcome) Type ¶ added in v0.9.0
func (o *WorkerOutcome) Type() flow.EventTrigger
Type returns the internal worker-outcome sentinel.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package localdispatcher provides the engine's default WorkerDispatcher (ADR-021 §2.4, SRD-036): an in-memory fetch-and-lock job store with per-job lock state and a local worker pool.
|
Package localdispatcher provides the engine's default WorkerDispatcher (ADR-021 §2.4, SRD-036): an in-memory fetch-and-lock job store with per-job lock state and a local worker pool. |