Skip to content

Commit a57d159

Browse files
authored
Add versioning documentation for workflows
Document versioning for workflows, including usage of WorkflowStub::getVersion() for managing changes without breaking running executions.
1 parent 4bdbbbf commit a57d159

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

docs/features/versioning.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
---
2+
sidebar_position: 13
3+
---
4+
5+
# Versioning
6+
7+
Since workflows can run for long periods, sometimes months or even years, it's common to need to make changes to a workflow definition while executions are still in progress. Without versioning, modifying workflow code that affects the execution path would cause non-determinism errors during replay.
8+
9+
The `WorkflowStub::getVersion()` method allows you to safely introduce changes to running workflows by creating versioned branch points.
10+
11+
```php
12+
use Workflow\Workflow;
13+
use Workflow\WorkflowStub;
14+
15+
class MyWorkflow extends Workflow
16+
{
17+
public function execute()
18+
{
19+
$version = yield WorkflowStub::getVersion(
20+
'my-change-id',
21+
WorkflowStub::DEFAULT_VERSION,
22+
1
23+
);
24+
25+
if ($version === WorkflowStub::DEFAULT_VERSION) {
26+
yield ActivityStub::make(OldActivity::class);
27+
} else {
28+
yield ActivityStub::make(NewActivity::class);
29+
}
30+
}
31+
}
32+
```
33+
34+
## How It Works
35+
36+
The `getVersion()` method takes three parameters:
37+
38+
- **changeId** - A unique identifier for this change point
39+
- **minSupported** - The minimum version this code still supports
40+
- **maxSupported** - The maximum (current) version for new executions
41+
42+
When a workflow encounters `getVersion()`:
43+
44+
- **New executions** record the `maxSupported` version and return it
45+
- **Replaying executions** return the previously recorded version
46+
47+
This allows new workflows to use the latest code path while existing workflows continue using their original path.
48+
49+
## Adding a New Version
50+
51+
Suppose you have an existing workflow that calls `prePatchActivity`:
52+
53+
```php
54+
class MyWorkflow extends Workflow
55+
{
56+
public function execute()
57+
{
58+
$result = yield ActivityStub::make(PrePatchActivity::class);
59+
60+
return $result;
61+
}
62+
}
63+
```
64+
65+
To replace it with `postPatchActivity` without breaking running workflows:
66+
67+
```php
68+
class MyWorkflow extends Workflow
69+
{
70+
public function execute()
71+
{
72+
$version = yield WorkflowStub::getVersion(
73+
'activity-change',
74+
WorkflowStub::DEFAULT_VERSION,
75+
1
76+
);
77+
78+
$result = $version === WorkflowStub::DEFAULT_VERSION
79+
? yield ActivityStub::make(PrePatchActivity::class)
80+
: yield ActivityStub::make(PostPatchActivity::class);
81+
82+
return $result;
83+
}
84+
}
85+
```
86+
87+
## Adding More Versions
88+
89+
When you need to make additional changes, increment `maxSupported`:
90+
91+
```php
92+
$version = yield WorkflowStub::getVersion(
93+
'activity-change',
94+
WorkflowStub::DEFAULT_VERSION,
95+
2
96+
);
97+
98+
$result = match($version) {
99+
WorkflowStub::DEFAULT_VERSION => yield ActivityStub::make(PrePatchActivity::class),
100+
1 => yield ActivityStub::make(PostPatchActivity::class),
101+
2 => yield ActivityStub::make(AnotherPatchActivity::class),
102+
};
103+
```
104+
105+
## Deprecating Old Versions
106+
107+
After all workflows using an old version have completed, you can drop support by increasing `minSupported`. This removes the need to maintain old code paths.
108+
109+
```php
110+
// After all DEFAULT_VERSION workflows have completed:
111+
$version = yield WorkflowStub::getVersion(
112+
'activity-change',
113+
1, // No longer supporting DEFAULT_VERSION
114+
2
115+
);
116+
117+
$result = match($version) {
118+
1 => yield ActivityStub::make(PostPatchActivity::class),
119+
2 => yield ActivityStub::make(AnotherPatchActivity::class),
120+
};
121+
```
122+
123+
If a workflow with a version older than `minSupported` tries to replay, it will throw a `VersionNotSupportedException`.
124+
125+
## Multiple Change Points
126+
127+
You can use multiple `getVersion()` calls in the same workflow for independent changes:
128+
129+
```php
130+
class MyWorkflow extends Workflow
131+
{
132+
public function execute()
133+
{
134+
$version1 = yield WorkflowStub::getVersion('change-1', WorkflowStub::DEFAULT_VERSION, 1);
135+
$version2 = yield WorkflowStub::getVersion('change-2', WorkflowStub::DEFAULT_VERSION, 1);
136+
137+
// Each change point is tracked independently
138+
}
139+
}
140+
```
141+
142+
**Important:** Each `changeId` should be unique within a workflow. The version is recorded in the workflow logs and will be replayed deterministically.

0 commit comments

Comments
 (0)