跳到主要内容
当前查看的是 1.37.x。最新版本为 1.45.x。

Step decisions

查看 Markdown

Execute returns a StepDecision. It moves to next Steps, closes the Flow, or both stops this branch and cancels other Steps.

Multiple next Steps​

GoTo starts one next Step. GoToMany starts multiple next Steps. Each Step movement has its own input and can also have its own Step options.

Go
return dex.GoToMany(
dex.MovementOf(carrierAStep{}, Quote{Carrier: "A", Price: 10}),
dex.MovementOf(carrierBStep{}, Quote{Carrier: "B", Price: 12}),
dex.MovementOf(winnerStep{}, quote),
), nil

Example: examples/go/primitives/step-decision/workflow.go

Close decisions​

DecisionWhat it does
GracefulCompleteStops this branch and triggers the Flow to prepare for completion. When all branches and Steps are stopped, the Flow completes.
DeadEndStops this branch only.
ForceCompleteCompletes the Flow immediately.
ForceFailFails the Flow immediately.

GracefulComplete and ForceComplete can return an output. ForceFail returns a failure reason. The Flow result returns each output with the Step type and Step execution ID. When multiple Steps complete gracefully, all their outputs return together.

A Flow can have no active Steps and still keep running. DeadEnd stops this branch without making a decision that triggers the Flow to complete.

Go
case "graceful":
return dex.GracefulComplete("done"), nil
case "dead-end":
return dex.GoToMany(
dex.MovementOf(branchWorker{}, "left"),
dex.MovementOf(branchWorker{}, "right"),
), nil

func (branchWorker) Execute(_ dex.Context, _ string) (*dex.StepDecision, error) {
return dex.DeadEnd(), nil
}

Example: examples/go/primitives/step-decision/workflow.go

Go
func (timeoutStep) Execute(
ctx dex.Context,
_ dex.None,
) (*dex.StepDecision, error) {
return dex.ForceFail("Workflow did not finish the task in time"), nil
}

func (taskStep) Execute(
ctx dex.Context,
_ bool,
) (*dex.StepDecision, error) {
return dex.ForceComplete("Workflow completed successfully"), nil
}

Example: examples/go/patterns/timeout/workflow.go

Cancel other Steps​

A StepDecision can cancel other active Steps.

  • CancelSteps selects active Steps by Step type.
  • CancelSiblingSteps selects active Steps that were triggered by the same parent Step execution.

An RPC can also cancel Steps by type. See Cancel running Steps. For how a running attempt observes cancellation, see Cancellation.

Go
func (winnerStep) Execute(_ dex.Context, quote Quote) (*dex.StepDecision, error) {
return dex.GoTo(recordQuote{}, quote).
CancelSteps(carrierAStep{}, carrierBStep{}), nil
}

Example: examples/go/primitives/step-decision/workflow.go

ForceCompleteIfChannelsEmpty​

ForceCompleteIfChannelsEmpty atomically checks whether all named Channels are empty. A Channel with queued messages is non-empty. After a message is consumed and committed to a Step, that Channel remains non-empty until the Step finishes processing Execute. If every named Channel is empty, it completes the Flow. Otherwise, it goes to other Steps.

Use it to drain Channels and complete the Flow, so the Flow can stay short. See Drain External Channel for the full example.

Go
return dex.ForceCompleteIfChannelsEmpty(
nil,
[]dex.ChannelDef{QueueChannel},
dex.MovementOf(processMessage{}, ""),
), nil

Example: examples/go/patterns/drain-channels/external-publishing/workflow.go