---
title: "Step decisions"
description: "Execute returns a StepDecision. It moves to next Steps, closes the"
canonical_url: "https://docs.superdurable.io/zh-Hans/reference/rust/1.37.x/flows-and-steps/step-decisions/"
source: "docs/reference-rust_versioned_docs/version-1.37.x/flows-and-steps/step-decisions.mdx"
locale: "zh-Hans"
---

# Step decisions

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

<a id="gotomulti"></a>

## 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](https://docs.superdurable.io/zh-Hans/reference/rust/1.37.x/flows-and-steps/step-options.md#stepoptions-override-per-stepexecution).

```rust
Ok(StepDecision::go_to_many([
    StepMovement::to(&CarrierA, quote_a),
    StepMovement::to(&CarrierB, quote_b),
    StepMovement::to(&Winner, winner_quote),
]))
```

Example: [examples/rust/src/primitives/step_decision/flow.rs](https://github.com/superdurable/dex/tree/main/examples/rust/src/primitives/step_decision/flow.rs)

<a id="close-decisions"></a>

## Close decisions

| Decision             | What it does                                                                                                                    |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **GracefulComplete** | Stops this branch and triggers the Flow to prepare for completion. When all branches and Steps are stopped, the Flow completes. |
| **DeadEnd**          | Stops this branch only.                                                                                                         |
| **ForceComplete**    | Completes the Flow immediately.                                                                                                 |
| **ForceFail**        | Fails 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.

```rust
"graceful" => Ok(StepDecision::graceful_complete(String::from("done"))),
"dead-end" => Ok(StepDecision::go_to_many([
    StepMovement::to(&BranchWorker, "left".to_string()),
    StepMovement::to(&BranchWorker, "right".to_string()),
])),

Ok(StepDecision::dead_end())
```

Example: [examples/rust/src/primitives/step_decision/flow.rs](https://github.com/superdurable/dex/tree/main/examples/rust/src/primitives/step_decision/flow.rs)

```rust
fn execute(&self, _context: &mut Context, _input: ()) -> HandlerResult<StepDecision> {
    Ok(StepDecision::force_fail("task exceeded graceful timeout"))
}

fn execute(&self, _context: &mut Context, _successful: bool) -> HandlerResult<StepDecision> {
    Ok(StepDecision::force_complete("task-completed".to_string()))
}
```

Example: [examples/rust/src/patterns/timeout/flow.rs](https://github.com/superdurable/dex/tree/main/examples/rust/src/patterns/timeout/flow.rs)

<a id="cancellation-on-stepdecision"></a>

## 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](https://docs.superdurable.io/zh-Hans/reference/server/runtime-data.md#cancel-running-steps). For how a
running attempt observes cancellation, see [Cancellation](https://docs.superdurable.io/zh-Hans/reference/rust/1.37.x/flows-and-steps/step-options.md#cancellation).

```rust
Ok(StepDecision::go_to(&RecordQuote, quote)
    .cancel_step(&CarrierA)
    .cancel_step(&CarrierB))
```

Example: [examples/rust/src/primitives/step_decision/flow.rs](https://github.com/superdurable/dex/tree/main/examples/rust/src/primitives/step_decision/flow.rs)

<a id="forcecompleteifchannelsempty"></a>

## 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](https://docs.superdurable.io/zh-Hans/design-patterns/draining-channel-for-external-publishing.md)
for the full example.

```rust
Ok(StepDecision::force_complete_if_channels_empty(
    (),
    StepMovement::to(&DrainChannel, ()),
    [channel_queue().when_empty()],
))
```

Example: [examples/rust/src/patterns/drain_channels/flow.rs](https://github.com/superdurable/dex/tree/main/examples/rust/src/patterns/drain_channels/flow.rs)
