This example demonstrates how to safely deploy versioned workflows using Cadence's versioning APIs. It shows how to handle workflow evolution while maintaining backward compatibility and enabling safe rollbacks.
The versioning sample implements a workflow that evolves through multiple versions (V1 → V2 → V3 → V4) with rollbacks, demonstrating:
- Safe Deployment: How to deploy new workflow versions without breaking existing executions
- Backward Compatibility: How to handle workflows started with older versions
- Rollback Capability: How to safely rollback to previous versions
- Version Isolation: How different versions can execute different logic paths
- Executes
FooActivityonly - Uses
workflow.DefaultVersionfor the change ID
- Supports both
FooActivityandBarActivity - Uses
workflow.GetVersion()withworkflow.ExecuteWithMinVersion()to handle both old and new workflows - Workflows started by V1 continue using
FooActivity
- Similar to V2 but uses standard
workflow.GetVersion()(withoutExecuteWithMinVersion) - All new workflows use version 1 of the change ID
- Only supports
BarActivity - Forces all workflows to use version 1 of the change ID
- Breaking change: Cannot execute workflows started by V1
workflow.GetVersion(): Determines which version of code to executeworkflow.ExecuteWithVersion(): Executes code with a specific versionworkflow.ExecuteWithMinVersion(): Executes code with minimum version requirementworkflow.DefaultVersion: Represents the original version before any changes
This example demonstrates a safe deployment strategy that allows you to:
- Deploy new versions while keeping old workers running
- Test compatibility before fully switching over
- Rollback safely if issues are discovered
- Gradually migrate workflows to new versions
- Single Workflow Limitation: This sample allows only one workflow at a time to simplify the signal handling mechanism. In production, you would typically handle multiple workflows.
- Signal Method: The workflow uses a simple signal method to stop gracefully, keeping the implementation straightforward.
- Breaking Changes: V4 demonstrates what happens when you introduce a breaking change - workflows started by V1 cannot be executed.
| Started By | V1 Worker | V2 Worker | V3 Worker | V4 Worker |
|---|---|---|---|---|
| V1 | ✅ | ✅ | ✅ | ❌ |
| V2 | ❌ | ✅ | ✅ | ✅ |
| V3 | ❌ | ✅ | ✅ | ✅ |
| V4 | ❌ | ✅ | ✅ | ✅ |
Make sure you have Cadence server running and the sample compiled:
# Build the sample
go build -o bin/versioning cmd/samples/recipes/versioning/*.go./bin/versioning -m worker -v 1./bin/versioning -m triggerWait for logs in the V1 worker to ensure that a workflow has been executed by worker V1.
Let's simulate a deployment from V1 to V2 and run a V2 worker alongside the V1 worker:
./bin/versioning -m worker -v 2The workflow should still be executed by worker V1.
Let's simulate that worker V1 is shut down and the workflow will be rescheduled to the V2 worker:
- Kill the process of worker V1 (Ctrl+C), then wait 5 seconds to see workflow rescheduling to worker V2 without errors.
Verify logs of the V2 worker - it should handle the workflow started by V1.
Let's continue the deployment and upgrade to V3, running a V3 worker alongside the V2 worker:
./bin/versioning -m worker -v 3The workflow should still be executed by worker V2.
Let's simulate that worker V2 is shut down and the workflow will be rescheduled to the V3 worker:
- Kill the process of worker V2, then wait 5 seconds to see workflow rescheduling to worker V3 without errors.
Verify logs of the V3 worker - it should handle the workflow started by V2.
Before upgrading to V4, we should ensure that the workflow has been stopped, otherwise it will fail. For this, we need to send a signal to stop it gracefully:
./bin/versioning -m stopYou should see that the workflow has been stopped.
Let's start a new workflow:
./bin/versioning -m triggerThe workflow will use version 1 of the change ID (V3's and V4's default).
Let's imagine that V3 has an issue and we need to rollback to V2. Let's start a worker V2:
./bin/versioning -m worker -v 2- Kill the process of worker V3, then wait for workflow rescheduling.
- Verify logs of V2 worker - V2 worker should handle workflows started by V3.
We decide to combine getting rid of support for V1 and make an upgrade straightforward to V4:
./bin/versioning -m worker -v 4- Kill the process of worker V2, then wait for workflow rescheduling.
- Verify logs of V4 worker - V4 worker should handle workflows started by V4.
# Start a worker with specific version
./bin/versioning -m worker -v <version>
# Start a new workflow
./bin/versioning -m trigger
# Stop the running workflow
./bin/versioning -m stopWhere <version> can be:
1orv1- Version 1 (FooActivity only, DefaultVersion)2orv2- Version 2 (FooActivity + BarActivity, DefaultVersion)3orv3- Version 3 (FooActivity + BarActivity, Version #1)4orv4- Version 4 (BarActivity only, Version #1)