---
title: "Workflow Patterns evaluation"
description: "The Workflow Patterns are a catalog of recurring behaviors in business"
canonical_url: "https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns/"
source: "docs/content/correctness-and-expressiveness/workflow-patterns.mdx"
locale: "en"
---

# Workflow Patterns evaluation

The Workflow Patterns are a catalog of recurring behaviors in business
processes. The Workflow Patterns Initiative defined them, led by Wil van der
Aalst and Arthur ter Hofstede. Researchers use them to compare workflow
languages and engines, such as BPMN, BPEL, and YAWL. Each pattern has an ID, a
name, and a precise definition. See the
[control-flow patterns](http://www.workflowpatterns.com/patterns/control/) for
the definitions.

This page rates Dex against the 43 control-flow patterns, WCP-1 to WCP-43. The
data, resource, and exception-handling patterns are not evaluated here.

<a id="rating-scheme"></a>

## Rating scheme

The ratings use the scheme of the published evaluations.

- **+** means direct support. One Dex construct meets every part of the
  definition. The application keeps no extra state for it.
- **+/-** means indirect support. Dex implements the pattern by composing
  several constructs, such as Channel signals, an Attribute counter, a lock,
  an RPC guard, or a loop that waits again. In a few rows, one part of the
  definition holds in a limited form, and the row says which. The published
  evaluations call this rating partial support.
- **-** means no support.

A Dex construct is part of the programming model. It is a Primitive, a Step
decision, a wait, or an SDK API that all five SDKs provide and document as
the standard way to do the job. The **Join** is such an API.

<a id="why-many-joins-are-indirect"></a>

## How Dex joins parallel branches

The **Join** synchronizes parallel branches inside one Flow. It is built on a
ChannelMap, and all five SDKs provide it.

- The split Step forks a round. **Fork** starts every branch and one join Step
  in the same decision. It gives them all the same round token.
- The token holds the round key and the branch count. The round key comes from
  the Step execution that forked the round. So the application keeps no
  counter and no key.
- Each branch reports one result when it ends.
- The join Step waits for every branch, for the first one, or for n of them.
  Its wait is an ordinary condition, so it combines with a Timer.
- Results of one round never count toward another round.
- When the join fires before every branch reports, the next round's split
  Step first waits for the rest of the previous round. This is the reset. It
  needs no extra Step.

When the work runs in child Flows, a **SubFlow** wait with **AllOf** is the
native join.

Ten patterns stay **+/-**, for these reasons:

- WCP-15 and WCP-36 add instances while others run. A Join needs the branch
  count when it forks, so neither example uses one. WCP-15 keeps a start
  counter and an intake flag under a lock, and its join waits again after
  each result. WCP-36 keeps a flag that closes admission, an AttributeMap of
  started bids, and a lock, and its join waits again after each result until
  its condition holds.
- WCP-33 queues the triggers of each incoming branch separately and keeps
  extra triggers for later firings. A Join counts results per round. It does
  not queue them per branch.
- WCP-38 must decide from the process structure that no more threads can
  reach the merge. That is a reachability question, not a count.
- WCP-17 and WCP-40 rest on an Attribute lock, which covers one **Execute**
  only.
- WCP-18, WCP-20, WCP-23, and WCP-39 are not joins, so the Join does not
  change them. Their rows give the reasons for their ratings.

<a id="join-limits"></a>

### Limits of the Join

The Join counts the results that branches report. It does not watch the
branch Steps. These limits follow.

- Each branch must report exactly once per round, on every exit path. That
  includes the Step that a failure route goes to. If a branch never reports,
  a join that waits for every branch waits forever. A branch that reports
  twice counts twice.
- A branch that is canceled from outside, for example by an RPC, never
  reports. A join that waits for every branch then waits forever. Cancel the
  join together with the branches, or wait for the join and a Timer with
  **AnyOf**.
- Canceling a branch from outside does not change the ratings. In Petri nets and YAWL,
  canceling a task inside a synchronized region also deadlocks the AND-join,
  unless the cancel region includes the join.
- A cancelling join's round is never reset. Its canceled branches never
  report, so a wait for the rest would never finish. In a loop, the next
  round forks a new round directly. Its round key keeps it apart from the old
  round.
- A join Step can be canceled after its wait consumed results but before its
  **Execute** result is saved. Whether those results return to the round
  depends on the server version. See
  [canceled Steps and consumed messages](https://docs.superdurable.io/reference/server/runtime-data.md#canceled-step-messages).
  When they are lost, a new join for the same round never fires.

<a id="how-the-ratings-were-checked"></a>

## How the ratings were checked

Every pattern has a runnable example in TypeScript, Python, Go, Java, and
Rust. Each example has an integration test against a real Dex Server. The test
asserts the behavior that defines the pattern. For example, the Deferred Choice
test sends two competing responses and checks that exactly one branch runs.

<a id="summary"></a>

## Summary

- 33 patterns have direct support (**+**).
- 10 patterns have indirect support (**+/-**).
- No pattern is unsupported (**-**).

<a id="comparison-with-a-published-evaluation"></a>

## Comparison with a published evaluation

A [published evaluation](https://doi.org/10.1016/j.infsof.2009.02.002) rated six workflow and BPM systems against the
same 43 control-flow patterns. Its authors are Wohed, Russell, ter Hofstede,
Andersson, and van der Aalst. It appeared in Information and Software
Technology 51(8), 2009 ([PDF](https://www.vdaalst.com/publications/p536.pdf)). In its Table 20, each system directly
supports 11 to 20 patterns and partly supports up to 6. Each system leaves 19
to 32 patterns unsupported. Dex leaves none unsupported.

<a id="results"></a>

## Results

The table names the Dex construct behind each rating.

| Pattern                                                                                                                                                  | Rating | Dex construct                                                                                                            | Examples                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [WCP-1 Sequence](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-1)                                                 | +      | **GoTo**                                                                                                                 | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/SequenceFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)                                                         |
| [WCP-2 Parallel Split](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-2)                                           | +      | **GoToMany**                                                                                                             | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ParallelSplitSynchronizationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)                                     |
| [WCP-3 Synchronization](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-3)                                          | +      | **Join**: **Fork** starts the branches and the join Step; the join waits for **ForAllBranches**                          | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ParallelSplitSynchronizationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)                                     |
| [WCP-4 Exclusive Choice](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-4)                                         | +      | **Execute** returns **GoTo** to one Step                                                                                 | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ExclusiveChoiceSimpleMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)                                       |
| [WCP-5 Simple Merge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-5)                                             | +      | Several Steps **GoTo** the same Step type                                                                                | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ExclusiveChoiceSimpleMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)                                       |
| [WCP-6 Multi-Choice](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-6)                                             | +      | **GoToMany** with a chosen subset of Steps                                                                               | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiChoiceSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)                |
| [WCP-7 Structured Synchronizing Merge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-7)                           | +      | **Join**: the choosing Step forks only the selected branches; the join waits for **ForAllBranches**                      | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiChoiceSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)                |
| [WCP-8 Multi-Merge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-8)                                              | +      | Each branch **GoTo** the same Step type; each arrival runs it again                                                      | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)                                   |
| [WCP-9 Structured Discriminator](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-9)                                 | +      | **Join** with **ForBranches** of 1; the next round's split Step resets it with **ForRemainingBranches**                  | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StructuredPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)                                                                |
| [WCP-10 Arbitrary Cycles](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-10)                                       | +      | **GoTo** any Step; the cycle has two entries and two exits                                                               | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/iteration.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/iteration.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/iteration.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ArbitraryCyclesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/iteration.rs)                                                                                      |
| [WCP-11 Implicit Termination](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-11)                                   | +      | **GracefulComplete** closes the Flow when no Step is active                                                              | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/termination.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/termination.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/termination.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ImplicitTerminationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/termination.rs)                                                                          |
| [WCP-12 Multiple Instances without Synchronization](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-12)             | +      | **GoToMany** of one Step type; nothing waits for them                                                                    | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultipleInstancesWithoutSynchronizationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)        |
| [WCP-13 Multiple Instances with a priori Design-Time Knowledge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-13) | +      | **Join** forks a fixed number of instances; the join waits for **ForAllBranches**                                        | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/DesignTimeMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)                    |
| [WCP-14 Multiple Instances with a priori Run-Time Knowledge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-14)    | +      | **Join** forks one instance per input item; the join waits for **ForAllBranches**                                        | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/RunTimeMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)                       |
| [WCP-15 Multiple Instances without a priori Run-Time Knowledge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-15) | +/-    | An **RPC** adds instances; an **Attribute** counts them; the join re-waits                                               | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/NoPriorKnowledgeMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)              |
| [WCP-16 Deferred Choice](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-16)                                        | +      | **AnyOf** over **Channels**; only the chosen message is consumed, so one branch runs                                     | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/DeferredChoiceFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)                                                                               |
| [WCP-17 Interleaved Parallel Routing](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-17)                           | +/-    | A shared **Attribute lock** on **Execute**; it covers one **Execute** only                                               | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/InterleavedParallelRoutingFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)                                                                   |
| [WCP-18 Milestone](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-18)                                              | +/-    | An **Attribute** marks the state; an **RPC** starts the task only while it holds                                         | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MilestoneFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)                                                                                    |
| [WCP-19 Cancel Task](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-19)                                            | +      | **RPC** result cancels a Step type and starts the next Step                                                              | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelTaskFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)                                                                               |
| [WCP-20 Cancel Case](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-20)                                            | +/-    | The Step that starts a **SubFlow** also waits for a cancel **Channel**, stops the child, and returns **ForceFail**       | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelCaseFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)                                                                               |
| [WCP-21 Structured Loop](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-21)                                        | +      | A pre-test Step **GoTo** the loop body or the exit                                                                       | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/iteration.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/iteration.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/iteration.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StructuredLoopFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/iteration.rs)                                                                                       |
| [WCP-22 Recursion](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-22)                                              | +      | A Step waits for a **SubFlow** of its own Flow type                                                                      | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/iteration.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/iteration.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/iteration.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/FactorialRecursionFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/iteration.rs)                                                                                   |
| [WCP-23 Transient Trigger](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-23)                                      | +/-    | An **RPC** guard under a shared **Attribute lock** accepts one trigger while a Step waits                                | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/triggers.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/triggers.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/triggers.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/TransientTriggerFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/triggers.rs)                                                                                         |
| [WCP-24 Persistent Trigger](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-24)                                     | +      | **Channel** messages stay queued until a Step consumes them                                                              | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/triggers.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/triggers.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/triggers.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/PersistentTriggerFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/triggers.rs)                                                                                        |
| [WCP-25 Cancel Region](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-25)                                          | +      | **RPC** result cancels several Step types at once                                                                        | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelRegionFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)                                                                             |
| [WCP-26 Cancel Multiple Instance Activity](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-26)                      | +      | **RPC** result cancels the instance Step type; finished instances keep their results                                     | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelMultipleInstanceTaskFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)                                                               |
| [WCP-27 Complete Multiple Instance Activity](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-27)                    | +      | **RPC** result cancels the instances and the join, then starts the next Step                                             | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CompleteMultipleInstanceTaskFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)                                                             |
| [WCP-28 Blocking Discriminator](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-28)                                 | +      | **Join** with **ForBranches** of 1; the next round starts only after **ForRemainingBranches** resets the join            | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/BlockingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)                                                                  |
| [WCP-29 Cancelling Discriminator](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-29)                               | +      | **Join** with **ForBranches** of 1; the join's decision cancels its sibling branches                                     | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancellingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)                                                                |
| [WCP-30 Structured Partial Join](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-30)                                | +      | **Join** with **ForBranches** of n; the next round's split Step resets it with **ForRemainingBranches**                  | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StructuredPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)                                                                |
| [WCP-31 Blocking Partial Join](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-31)                                  | +      | **Join** with **ForBranches** of n; the next round starts only after **ForRemainingBranches** resets the join            | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/BlockingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)                                                                  |
| [WCP-32 Cancelling Partial Join](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-32)                                | +      | **Join** with **ForBranches** of n; the join's decision cancels its sibling branches                                     | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancellingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)                                                                |
| [WCP-33 Generalised AND-Join](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-33)                                   | +/-    | **AllOf** over **Channels**; extra signals wait for the next firing                                                      | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/and-join-and-threads.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/and_join_and_threads.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/and_join_and_threads.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/GeneralizedAndJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/and_join_and_threads.rs)                                       |
| [WCP-34 Static Partial Join for Multiple Instances](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-34)             | +      | **Join** over m instances with **ForBranches** of n; the next round's split Step resets it with **ForRemainingBranches** | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StaticPartialJoinForMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_partial_joins.rs)     |
| [WCP-35 Cancelling Partial Join for Multiple Instances](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-35)         | +      | **Join** over m instances with **ForBranches** of n; the join's decision cancels its sibling instances                   | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancellingPartialJoinForMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_partial_joins.rs) |
| [WCP-36 Dynamic Partial Join for Multiple Instances](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-36)            | +/-    | An **RPC** adds instances; the join re-waits and tests its condition                                                     | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/DynamicPartialJoinForMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_partial_joins.rs)    |
| [WCP-37 Local Synchronizing Merge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-37)                              | +      | **Join**: the diverging Step forks the active branches; the join waits for **ForAllBranches**                            | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiChoiceSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)                |
| [WCP-38 General Synchronizing Merge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-38)                            | +/-    | An **Attribute** counts the threads that can still reach the merge; reaching 0 publishes a sentinel                      | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/GeneralSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)                    |
| [WCP-39 Critical Section](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-39)                                       | +/-    | A one-message **Channel** acts as a token                                                                                | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CriticalSectionFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)                                                                              |
| [WCP-40 Interleaved Routing](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-40)                                    | +/-    | A shared **Attribute lock** on **Execute**, then **ForN**; the lock covers one **Execute** only                          | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/InterleavedRoutingFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)                                                                           |
| [WCP-41 Thread Merge](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-41)                                           | +      | **Join** over the threads of one Step type; the merge waits for **ForAllBranches**                                       | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/and-join-and-threads.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/and_join_and_threads.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/and_join_and_threads.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ThreadSplitMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/and_join_and_threads.rs)                                         |
| [WCP-42 Thread Split](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-42)                                           | +      | **GoToMany** of one Step type                                                                                            | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/and-join-and-threads.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/and_join_and_threads.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/and_join_and_threads.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ThreadSplitMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/and_join_and_threads.rs)                                         |
| [WCP-43 Explicit Termination](https://docs.superdurable.io/correctness-and-expressiveness/workflow-patterns.md#wcp-43)                                   | +      | **ForceComplete** closes the Flow and cancels other Steps                                                                | [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/termination.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/termination.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/termination.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ExplicitTerminationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/termination.rs)                                                                          |

<a id="what-the-ratings-rest-on"></a>

## What the ratings rest on

The ratings depend on these Dex behaviors.

- **GracefulComplete** closes the Flow only when no Step is active.
- **DeadEnd** ends one branch and never closes the Flow.
- **ForceComplete** closes the Flow at once and cancels the other Steps.
- **AnyOf** consumes messages only from the condition it selects.
- A Channel message stays queued until a Step consumes it.
- A decision or an RPC cancels Steps by Step type. Dex does not stop a canceled
  method's code. The method keeps running until it checks for cancellation and
  returns.
- Only one Step method or RPC holds an Attribute lock at a time.
- A SubFlow keeps running when its parent closes.
- A **Join** keys each round by the Step execution that forked it. Results of
  one round never satisfy the join of another round.
- A Step method publishes only when it succeeds. So a retried branch reports
  its result once.
- A decision can limit its cancellation to sibling Steps. Siblings are the
  Steps that one decision started together. When an RPC forked a round with
  an explicit round key, the branches are siblings of every Step that this
  RPC name ever started. Cancel such branches explicitly by Step type.

See [Step](https://docs.superdurable.io/concepts/step.md), [Channel](https://docs.superdurable.io/concepts/primitives/channel.md), and
[SubFlow](https://docs.superdurable.io/concepts/primitives/subflow.md) for these concepts.

<a id="pattern-details"></a>

## Pattern details

<a id="wcp-1"></a>

### WCP-1 Sequence

**What it is.** A task starts only after the task before it finishes. Both tasks belong to the same process. See the [official definition](http://www.workflowpatterns.com/patterns/control/basic/wcp1.php).

**How Dex implements it.** Each Step's **Execute** returns **GoTo** for the next Step. The example runs ReceiveOrder, CheckInventory, and ShipOrder in order.

**Rating:** **+**. **GoTo** is the sequence construct.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/SequenceFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)

<a id="wcp-2"></a>

### WCP-2 Parallel Split

**What it is.** One branch splits into two or more branches. The branches run at the same time. See the [official definition](http://www.workflowpatterns.com/patterns/control/basic/wcp2.php).

**How Dex implements it.** A Step returns **GoToMany** with one Step movement per branch. The example splits an order into packing and payment.

**Rating:** **+**. **GoToMany** is the split construct.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ParallelSplitSynchronizationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)

<a id="wcp-3"></a>

### WCP-3 Synchronization

**What it is.** Two or more branches converge into one. The next branch starts only after every incoming branch has finished. See the [official definition](http://www.workflowpatterns.com/patterns/control/basic/wcp3.php).

**How Dex implements it.** The split Step calls **Fork** on a **Join**. **Fork** returns the branches and the join Step for one **GoToMany**, and gives each of them the same round token. Each branch ends with **EndBranch**, which reports its result. The join Step waits for **ForAllBranches**.

**Rating:** **+**. The Join is the join construct. **Fork** counts the branches and keys the round, so the application keeps no count.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ParallelSplitSynchronizationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)

<a id="wcp-4"></a>

### WCP-4 Exclusive Choice

**What it is.** One branch splits into several. Control passes to exactly one of them. A condition picks which one. See the [official definition](http://www.workflowpatterns.com/patterns/control/basic/wcp4.php).

**How Dex implements it.** **Execute** evaluates the condition and returns **GoTo** for one Step. The example routes a claim to manual review or automatic approval by amount.

**Rating:** **+**. A decision with one **GoTo** is the choice construct.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ExclusiveChoiceSimpleMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)

<a id="wcp-5"></a>

### WCP-5 Simple Merge

**What it is.** Two or more branches converge into one. Each arrival passes control on. The pattern assumes only one incoming branch is active at a time. See the [official definition](http://www.workflowpatterns.com/patterns/control/basic/wcp5.php).

**How Dex implements it.** Each branch returns **GoTo** for the same Step type. The example's two review branches both go to CloseClaim.

**Rating:** **+**. A shared **GoTo** target is the merge.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/basic-control-flow.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/basic_control_flow.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/basic_control_flow.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ExclusiveChoiceSimpleMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/basic_control_flow.rs)

<a id="wcp-6"></a>

### WCP-6 Multi-Choice

**What it is.** One branch splits into several. Control passes to one or more of them. A condition picks the set. See the [official definition](http://www.workflowpatterns.com/patterns/control/advanced_branching/wcp6.php).

**How Dex implements it.** **Execute** builds the list of selected Steps and returns **GoToMany** for them. The example picks email, SMS, or push notifications from the input.

**Rating:** **+**. **GoToMany** with a computed list is the multi-choice construct.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiChoiceSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)

<a id="wcp-7"></a>

### WCP-7 Structured Synchronizing Merge

**What it is.** Branches started by an earlier Multi-Choice converge into one. The merge waits for every branch that was started, and only those. It belongs to one Multi-Choice in a structured model. See the [official definition](http://www.workflowpatterns.com/patterns/control/advanced_branching/wcp7.php).

**How Dex implements it.** The choosing Step passes only the selected branches to **Fork**. Each branch ends with **EndBranch**. The join waits for **ForAllBranches**, so it waits for exactly the branches that started.

**Rating:** **+**. The branch count comes from **Fork**. The application never passes it to the join.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiChoiceSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)

<a id="wcp-8"></a>

### WCP-8 Multi-Merge

**What it is.** Several branches converge into one. Each arrival passes control on separately. The next task runs once per arrival. See the [official definition](http://www.workflowpatterns.com/patterns/control/advanced_branching/wcp8.php).

**How Dex implements it.** Each branch returns **GoTo** for the same Step type. Dex starts a new execution of that Step for each arrival.

**Rating:** **+**. Each **GoTo** creates its own Step execution.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)

<a id="wcp-9"></a>

### WCP-9 Structured Discriminator

**What it is.** After a parallel split, the first branch to arrive passes control on. Later arrivals do not. The construct resets once every branch has arrived. See the [official definition](http://www.workflowpatterns.com/patterns/control/advanced_branching/wcp9.php).

**How Dex implements it.** The split Step forks each round of a **Join**. The join waits for **ForBranches** of 1 and passes control on. It also starts the next round's split Step with the round token. That Step's **WaitFor** waits for **ForRemainingBranches**, which consumes the other results of the round. That is the reset. The Step then forks the next round. The example records the ignored results in an Attribute.

**Rating:** **+**. The Join keys each round by the Step execution that forked it, so a late result never passes control on. The reset needs no extra Step and no round counter.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StructuredPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)

<a id="wcp-10"></a>

### WCP-10 Arbitrary Cycles

**What it is.** A process can contain a loop with more than one entry point or exit point. See the [official definition](http://www.workflowpatterns.com/patterns/control/structural/wcp10.php).

**How Dex implements it.** Steps **GoTo** each other freely, including Steps that already ran. The example's draft and edit loop has two entry points and two exit points.

**Rating:** **+**. **GoTo** can target any Step.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/iteration.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/iteration.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/iteration.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ArbitraryCyclesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/iteration.rs)

<a id="wcp-11"></a>

### WCP-11 Implicit Termination

**What it is.** A process ends when no work remains, now or later. No dedicated end node is needed. See the [official definition](http://www.workflowpatterns.com/patterns/control/structural/wcp11.php).

**How Dex implements it.** Each branch that finishes returns **GracefulComplete**. The Flow closes only when no Step is active.

**Rating:** **+**. **GracefulComplete** waits for the last active Step.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/termination.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/termination.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/termination.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ImplicitTerminationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/termination.rs)

<a id="wcp-12"></a>

### WCP-12 Multiple Instances without Synchronization

**What it is.** A task runs as several independent instances in one process instance. Nothing waits for them to finish. See the [official definition](http://www.workflowpatterns.com/patterns/control/multiple_instance/wcp12.php).

**How Dex implements it.** A Step returns **GoToMany** with one execution of the same Step type per instance. The Flow continues on another branch without a join.

**Rating:** **+**. **GoToMany** starts the instances, and no Step waits for them.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultipleInstancesWithoutSynchronizationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)

<a id="wcp-13"></a>

### WCP-13 Multiple Instances with a priori Design-Time Knowledge

**What it is.** The number of instances is fixed in the model. The instances run at the same time. The process continues after all of them finish. See the [official definition](http://www.workflowpatterns.com/patterns/control/multiple_instance/wcp13.php).

**How Dex implements it.** A Step forks a **Join** with a fixed list of instances. Each instance ends with **EndBranch**. The join waits for **ForAllBranches**.

**Rating:** **+**. Each instance is one branch of the Join, and **Fork** counts them.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/DesignTimeMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)

<a id="wcp-14"></a>

### WCP-14 Multiple Instances with a priori Run-Time Knowledge

**What it is.** The number of instances is known at run time, before they start. The instances run at the same time. The process continues after all of them finish. See the [official definition](http://www.workflowpatterns.com/patterns/control/multiple_instance/wcp14.php).

**How Dex implements it.** A Step builds one instance for each item in its input and forks a **Join** with that list. The join waits for **ForAllBranches**.

**Rating:** **+**. The number of instances is the length of the list that **Fork** receives. The application keeps no count.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/RunTimeMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)

<a id="wcp-15"></a>

### WCP-15 Multiple Instances without a priori Run-Time Knowledge

**What it is.** The number of instances is not known until the last one finishes. New instances can start while others run. The process continues after all of them finish. See the [official definition](http://www.workflowpatterns.com/patterns/control/multiple_instance/wcp15.php).

**How Dex implements it.** An **RPC** starts each new instance through its next Steps and counts it in an **Attribute**. Another RPC prevents further instances from starting. The join waits for one result at a time. It loops until no new instances can start and every instance has reported.

**Rating:** **+/-**. The join composes an RPC, an Attribute counter, and a loop that waits again after each result.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/NoPriorKnowledgeMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_creation.rs)

<a id="wcp-16"></a>

### WCP-16 Deferred Choice

**What it is.** The environment chooses between branches. Every branch stays possible until one of them starts. Then the others are withdrawn. See the [official definition](http://www.workflowpatterns.com/patterns/control/state/wcp16.php).

**How Dex implements it.** One Step waits with **AnyOf** over one **Channel** per branch. Dex consumes the message of the selected condition only. **Execute** goes to the branch that matches it.

**Rating:** **+**. **AnyOf** decides the race, and only one branch ever starts.

**Design pattern:** [Deferred Choice](https://docs.superdurable.io/design-patterns/deferred-choice.md).

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/DeferredChoiceFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)

<a id="wcp-17"></a>

### WCP-17 Interleaved Parallel Routing

**What it is.** A set of tasks runs in any order that a partial order allows. Each task runs once. No two of them run at the same time. See the [official definition](http://www.workflowpatterns.com/patterns/control/state/wcp17.php).

**How Dex implements it.** Every task's **Execute** declares a lock on the same **Attribute**. **GoTo** encodes the partial order. A join waits for **ForN** signals from the tasks.

**Rating:** **+/-**. The routing composes a lock with Channel signals. The lock covers one **Execute** only. It does not cover a **WaitFor** or a task that spans several Steps.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/InterleavedParallelRoutingFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)

<a id="wcp-18"></a>

### WCP-18 Milestone

**What it is.** A task can start only while the process is at a given state. Once the process moves past that state, the task can no longer start. See the [official definition](http://www.workflowpatterns.com/patterns/control/state/wcp18.php).

**How Dex implements it.** An **Attribute** marks that the change window is open. An **RPC** starts the task through its next Steps only while the Attribute is set. A later Step clears it.

**Rating:** **+/-**. A Step cannot test another branch's state, so an Attribute and an RPC guard stand in for it.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MilestoneFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)

<a id="wcp-19"></a>

### WCP-19 Cancel Task

**What it is.** An enabled task is withdrawn before it starts. A running task is stopped where possible. See the [official definition](http://www.workflowpatterns.com/patterns/control/cancellation/wcp19.php).

**How Dex implements it.** An **RPC** result cancels the waiting Step by Step type and starts another Step. Dex applies both changes together.

**Rating:** **+**. Canceling Steps is a built-in RPC result.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelTaskFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)

<a id="wcp-20"></a>

### WCP-20 Cancel Case

**What it is.** A whole process instance is removed. This includes running tasks, future tasks, and "all sub-processes". It is recorded as unsuccessful. See the [official definition](http://www.workflowpatterns.com/patterns/control/cancellation/wcp20.php).

**How Dex implements it.** The Step that starts a **SubFlow** waits with **AnyOf** for the child or a cancel **Channel**. On cancel, it reads the child's Flow ID with **SubFlow\.getFlowId**, stops the child with Client **StopFlow**, and returns **ForceFail**. **ForceFail** cancels every other active Step.

**Rating:** **+/-**. Client **StopFlow** alone leaves a running SubFlow alive, so the example composes a cancel Channel, an explicit stop, and **ForceFail**.

**Design pattern:** [Cancel with Child Flows](https://docs.superdurable.io/design-patterns/cancel-case.md).

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelCaseFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)

<a id="wcp-21"></a>

### WCP-21 Structured Loop

**What it is.** A task or sub-process repeats while a condition holds. The condition is tested before or after each pass. The loop has one entry and one exit. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp21.php).

**How Dex implements it.** A pre-test Step **GoTo** the loop body or the exit. The body **GoTo** the pre-test again.

**Rating:** **+**. **GoTo** forms the loop.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/iteration.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/iteration.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/iteration.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StructuredLoopFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/iteration.rs)

<a id="wcp-22"></a>

### WCP-22 Recursion

**What it is.** A task can invoke itself, directly or through an ancestor. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp22.php).

**How Dex implements it.** A Step waits for a **SubFlow** of its own Flow type. The example computes a factorial this way.

**Rating:** **+**. A SubFlow can run the same Flow type as its parent.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/iteration.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/iteration.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/iteration.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/FactorialRecursionFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/iteration.rs)

<a id="wcp-23"></a>

### WCP-23 Transient Trigger

**What it is.** A signal triggers a task only if the task is already waiting. A signal that arrives when no task waits is lost. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp23.php).

**How Dex implements it.** The Step's **WaitFor** sets an **Attribute** to record that it is waiting. An **RPC** declares a lock on that Attribute. It accepts a trigger only while the Attribute is set, and it clears the Attribute when it accepts one. Later triggers are dropped.

**Rating:** **+/-**. Channel messages persist, so the example composes an Attribute, a lock, and an RPC guard to drop triggers.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/triggers.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/triggers.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/triggers.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/TransientTriggerFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/triggers.rs)

<a id="wcp-24"></a>

### WCP-24 Persistent Trigger

**What it is.** A signal is kept until a task can act on it. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp24.php).

**How Dex implements it.** An **RPC** publishes the signal to a **Channel**. The message stays queued until a Step's **WaitFor** consumes it.

**Rating:** **+**. Channel messages persist by design.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/triggers.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/triggers.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/triggers.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/PersistentTriggerFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/triggers.rs)

<a id="wcp-25"></a>

### WCP-25 Cancel Region

**What it is.** A set of tasks is withdrawn together. The tasks need not be connected. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp25.php).

**How Dex implements it.** An **RPC** result names several Step types to cancel and starts the next Step. Other Steps keep running.

**Rating:** **+**. One RPC result cancels any set of Step types.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelRegionFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)

<a id="wcp-26"></a>

### WCP-26 Cancel Multiple Instance Activity

**What it is.** A multiple-instance task can be canceled at any time. Unfinished instances are withdrawn. Finished instances keep their results. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp26.php).

**How Dex implements it.** An **RPC** result cancels the instance Step type. Instances that already completed are unaffected.

**Rating:** **+**. Canceling by Step type covers every open instance.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancelMultipleInstanceTaskFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)

<a id="wcp-27"></a>

### WCP-27 Complete Multiple Instance Activity

**What it is.** A multiple-instance task can be forced to complete. Remaining instances are withdrawn, and the process continues. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp27.php).

**How Dex implements it.** An **RPC** result cancels the instances and their join, then starts the next Step with the results so far.

**Rating:** **+**. One RPC result both cancels the instances and starts the next Step.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/cancellation.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/cancellation.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/cancellation.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CompleteMultipleInstanceTaskFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/cancellation.rs)

<a id="wcp-28"></a>

### WCP-28 Blocking Discriminator

**What it is.** The first branch to arrive passes control on. The definition says "Subsequent enablements of incoming branches are blocked until the Blocking Discriminator has reset." It resets once every active branch has arrived. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp28.php).

**How Dex implements it.** The split Step forks each round of a **Join**, and the join waits for **ForBranches** of 1. The next round's split Step waits for **ForRemainingBranches** of the previous round before it forks again. Until then, no branch of the next round exists, so a next-round signal stays queued and has no effect.

**Rating:** **+**. The reset blocks the next round by construction. It needs no extra Step and no round counter.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/BlockingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)

<a id="wcp-29"></a>

### WCP-29 Cancelling Discriminator

**What it is.** The first branch to arrive passes control on. It also cancels the other branches. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp29.php).

**How Dex implements it.** The split Step forks the branches with a **Join**, and the join waits for **ForBranches** of 1. Its decision cancels its sibling Steps of the branch Step types. **Fork** starts the branches and the join in one decision, so the siblings are exactly this round's branches.

**Rating:** **+**. One join Step both fires and cancels. A canceled branch never reports a result.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancellingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)

<a id="wcp-30"></a>

### WCP-30 Structured Partial Join

**What it is.** After a parallel split into m branches, control passes on once n of them arrive. Later arrivals do not pass control on. The join resets after every branch arrives. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp30.php).

**How Dex implements it.** The split Step forks each round of a **Join** with m branches. The join waits for **ForBranches** of n. The next round's split Step waits for **ForRemainingBranches** of the previous round, which consumes the other m - n results. Then it forks the next round. The example records the ignored results in an Attribute.

**Rating:** **+**. As in WCP-9, the Join keys each round, and the reset needs no extra Step and no round counter.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StructuredPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)

<a id="wcp-31"></a>

### WCP-31 Blocking Partial Join

**What it is.** Control passes on once n of m branches arrive. Further enablements are blocked until the join resets. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp31.php).

**How Dex implements it.** This works like WCP-28 with **ForBranches** of n. The next round's branches start only after **ForRemainingBranches** resets the join, so next-round signals stay queued until then.

**Rating:** **+**. As in WCP-28, the reset blocks the next round by construction.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/BlockingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)

<a id="wcp-32"></a>

### WCP-32 Cancelling Partial Join

**What it is.** Control passes on once n of m branches arrive. The remaining branches are canceled. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp32.php).

**How Dex implements it.** This works like WCP-29 with **ForBranches** of n. The join's decision cancels its sibling branches.

**Rating:** **+**. As in WCP-29, one join Step both fires and cancels.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/partial-joins.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/partial_joins.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/partial_joins.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancellingPartialJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/partial_joins.rs)

<a id="wcp-33"></a>

### WCP-33 Generalised AND-Join

**What it is.** Control passes on once every incoming branch has delivered a trigger. Extra triggers on a branch are kept for later firings. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp33.php).

**How Dex implements it.** The join waits with **AllOf** over one **Channel** per incoming branch. Extra messages stay queued, and the join loops to fire again.

**Rating:** **+/-**. The join composes Channel signals with an **AllOf** wait. The branches must publish the signals.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/and-join-and-threads.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/and_join_and_threads.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/and_join_and_threads.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/GeneralizedAndJoinFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/and_join_and_threads.rs)

<a id="wcp-34"></a>

### WCP-34 Static Partial Join for Multiple Instances

**What it is.** m instances run. The next task starts once n of them complete. The rest still finish, and the join resets after all complete. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp34.php).

**How Dex implements it.** In each round, the split Step forks a **Join** with m instances of one Step type. The join waits for **ForBranches** of n. The next round's split Step waits for **ForRemainingBranches** of the previous round, then forks the next round. The example records the ignored results in an Attribute.

**Rating:** **+**. As in WCP-30, with instances as the branches.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/StaticPartialJoinForMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_partial_joins.rs)

<a id="wcp-35"></a>

### WCP-35 Cancelling Partial Join for Multiple Instances

**What it is.** m instances run. Once n of them complete, the next task starts and the rest are canceled. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp35.php).

**How Dex implements it.** The split Step forks m instances with a **Join**, and the join waits for **ForBranches** of n. Its decision cancels its sibling Steps of the instance Step type.

**Rating:** **+**. As in WCP-32, with instances as the branches.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CancellingPartialJoinForMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_partial_joins.rs)

<a id="wcp-36"></a>

### WCP-36 Dynamic Partial Join for Multiple Instances

**What it is.** Instances can start while others run, until adding is disabled. A completion condition is checked after each instance finishes. When it holds, the next task starts. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp36.php).

**How Dex implements it.** An **RPC** starts a new instance unless an **Attribute** flag says new instances are disabled. The join waits for one result at a time and tests its condition. When the condition holds, the join sets the flag and continues.

**Rating:** **+/-**. The join composes an RPC, an Attribute flag, a shared lock, and a loop that waits again after each result.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multiple-instances.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multiple_instances.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multiple_instances.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/DynamicPartialJoinForMultipleInstancesFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multiple_instances/instance_partial_joins.rs)

<a id="wcp-37"></a>

### WCP-37 Local Synchronizing Merge

**What it is.** Branches converge, and the merge waits for every active branch. It decides how many to wait for from information it has locally. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp37.php).

**How Dex implements it.** As in WCP-7, the diverging Step forks a **Join** with only the active branches. The join waits for **ForAllBranches**.

**Rating:** **+**. The local information is the branch count in the round token, which **Fork** creates.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/MultiChoiceSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)

<a id="wcp-38"></a>

### WCP-38 General Synchronizing Merge

**What it is.** The merge waits for every active branch, or until "it is not possible that any branch that has not yet been enabled will be enabled at any future time". It works in any process, including unstructured ones with loops. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp38.php).

**How Dex implements it.** An **Attribute** counts the threads that can still reach the merge. Every Step that changes the count declares a lock on that Attribute. The Step that brings the count to 0 also publishes a "done" message to a **Channel**. The merge Step waits for that message.

**Rating:** **+/-**. The pattern expects the merge to decide reachability from the process structure. In Dex, application code decides it at each **GoTo**.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/multi-choice-and-merges.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/multi_choice_and_merges.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/multi_choice_and_merges.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/GeneralSynchronizingMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/multi_choice_and_merges.rs)

<a id="wcp-39"></a>

### WCP-39 Critical Section

**What it is.** Several sub-processes are marked as critical sections. Only one of them runs at a time in a process instance. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp39.php).

**How Dex implements it.** A **Channel** holds a single token message. Each section's first Step waits for the token, and its last Step publishes it back.

**Rating:** **+/-**. An Attribute lock covers one Step method only, so a section of several Steps uses a one-message Channel as a token.

**Design pattern:** [Critical Section](https://docs.superdurable.io/design-patterns/critical-section.md).

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/CriticalSectionFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)

<a id="wcp-40"></a>

### WCP-40 Interleaved Routing

**What it is.** Each task in a set runs once, in any order. No two of them run at the same time. The next task starts after all of them finish. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp40.php).

**How Dex implements it.** Every task's **Execute** declares a lock on the same **Attribute**. A join waits for **ForN** signals from the tasks.

**Rating:** **+/-**. The routing composes a lock with Channel signals. As in WCP-17, the lock covers one **Execute** only.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/state-based.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/state_based.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/state_based.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/InterleavedRoutingFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/state_based.rs)

<a id="wcp-41"></a>

### WCP-41 Thread Merge

**What it is.** A given number of threads in one branch merge into a single thread. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp41.php).

**How Dex implements it.** A Step forks a **Join** with the given number of threads, all of one Step type. Each thread ends with **EndBranch**. The merge Step waits for **ForAllBranches**.

**Rating:** **+**. Each thread is one branch of the Join, and **Fork** counts them.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/and-join-and-threads.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/and_join_and_threads.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/and_join_and_threads.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ThreadSplitMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/and_join_and_threads.rs)

<a id="wcp-42"></a>

### WCP-42 Thread Split

**What it is.** A branch starts a given number of threads. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp42.php).

**How Dex implements it.** A Step returns **GoToMany** with that many executions of one Step type.

**Rating:** **+**. **GoToMany** starts the threads.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/and-join-and-threads.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/and_join_and_threads.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/and_join_and_threads.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ThreadSplitMergeFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/and_join_and_threads.rs)

<a id="wcp-43"></a>

### WCP-43 Explicit Termination

**What it is.** A process ends when it reaches a given end node. Remaining work is canceled, and the process is recorded as successful. See the [official definition](http://www.workflowpatterns.com/patterns/control/new/wcp43.php).

**How Dex implements it.** A Step returns **ForceComplete**. Dex closes the Flow at once and cancels every other active Step.

**Rating:** **+**. **ForceComplete** is the explicit end.

**Examples:** [TS](https://github.com/superdurable/dex/blob/main/examples/typescript/src/patterns/workflow-patterns/termination.ts) · [Python](https://github.com/superdurable/dex/blob/main/examples/python/dex_examples/patterns/workflow_patterns/termination.py) · [Go](https://github.com/superdurable/dex/blob/main/examples/go/patterns/workflow-patterns/termination.go) · [Java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/patterns/workflowpatterns/ExplicitTerminationFlow.java) · [Rust](https://github.com/superdurable/dex/blob/main/examples/rust/src/workflow_patterns/termination.rs)
