Skip to content

Commit f71b40e

Browse files
committed
Update sample code and instructions
1 parent e592351 commit f71b40e

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
11
# Versioning
22

33
This directory contains a Function app that demonstrates how to make changes to an orchestrator function without breaking existing orchestration instances.
4+
5+
The orchestrator function has two code paths:
6+
7+
1. The old path invoking `activity_a`.
8+
2. The new path invoking `activity_b` instead.
9+
10+
While `defaultVersion` in `host.json` is set to `1.0`, the orchestrator will always follow the first path, producing the following output:
11+
12+
```
13+
Orchestration version: 1.0
14+
Suborchestration version: 1.0
15+
Hello from A!
16+
```
17+
18+
When `defaultVersion` in `host.json` is updated (for example, to `2.0`), *new orchestration instances* will follow the new path, producing the following output:
19+
20+
```
21+
Orchestration version: 2.0
22+
Suborchestration version: 2.0
23+
Hello from B!
24+
```
25+
26+
What happens to existing orchestration instances that were started before the `defaultVersion` change? Waiting for an external event in the middle of the orchestrator provides a convenient opportunity to emulate a deployment while orchestration instances are still running:
27+
28+
1. Create a new orchestration by invoking the HTTP trigger (`http_start`).
29+
2. Wait for the orchestration to reach the point where it is waiting for an external event.
30+
3. Stop the app.
31+
4. Change `defaultVersion` in `host.json` to `2.0`.
32+
5. Deploy and start the updated app.
33+
6. Trigger the external event.
34+
7. Observe that the orchestration output.
35+
36+
```
37+
Orchestration version: 1.0
38+
Suborchestration version: 2.0
39+
Hello from A!
40+
```
41+
42+
Note that the value returned by `context.version` is permanently associated with the orchestrator instance and is not impacted by the `defaultVersion` change. As a result, the orchestrator follows the old execution path to guarantee deterministic replay behavior.
43+
44+
However, the suborchestration version is `2.0` because it was invoked this suborchestration was created *after* the `defaultVersion` change.

samples-v2/orchestration_versioning/function_app.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,32 @@ async def http_start(req: func.HttpRequest, client):
1515

1616
@myApp.orchestration_trigger(context_name="context")
1717
def my_orchestrator(context: df.DurableOrchestrationContext):
18+
# context.version contains the value of defaultVersion in host.json
19+
# at the moment when the orchestration was created.
1820
if (context.version == "1.0"):
1921
# Legacy code path
20-
activity_result = yield context.call_activity('say_hello', "v1.0")
22+
activity_result = yield context.call_activity('activity_a')
2123
else:
2224
# New code path
23-
activity_result = yield context.call_activity('say_hello', f"v{context.version}")
25+
activity_result = yield context.call_activity('activity_b')
2426

25-
# While the orchestration is waiting for the external event,
26-
# stop the app, update the defaultVersion in host.json to "2.0",
27-
# then restart the app and send a "Continue" event.
28-
# This orchestration instance should continue with the old version.
27+
# Provide an opportunity to update and restart the app
2928
context.set_custom_status("Waiting for Continue event...")
3029
yield context.wait_for_external_event("Continue")
3130
context.set_custom_status("Continue event received")
3231

33-
# New orchestration instances (including sub-orchestrations)
34-
# will use the current defaultVersion specified in host.json.
32+
# New sub-orchestrations will use the current defaultVersion specified in host.json
3533
sub_result = yield context.call_sub_orchestrator('my_sub_orchestrator')
3634
return [f'Orchestration version: {context.version}', f'Suborchestration version: {sub_result}', activity_result]
3735

3836
@myApp.orchestration_trigger(context_name="context")
3937
def my_sub_orchestrator(context: df.DurableOrchestrationContext):
4038
return context.version
4139

42-
@myApp.activity_trigger(input_name="city")
43-
def say_hello(city: str) -> str:
44-
return f"Hello {city}!"
40+
@myApp.activity_trigger()
41+
def activity_a() -> str:
42+
return f"Hello from A!"
43+
44+
@myApp.activity_trigger()
45+
def activity_b() -> str:
46+
return f"Hello from B!"

0 commit comments

Comments
 (0)