This sample shows how to safely update a workflow in stages using Temporalio::Workflow.patch and Temporalio::Workflow.deprecate_patch.
To run, first see README.md for prerequisites. Then follow the stages below.
To simulate our initial workflow, start a worker in another terminal
bundle exec ruby worker.rb initialNow start a workflow:
bundle exec ruby starter.rb start initial-idThis will output Started workflow with id initial-id.
Now query the workflow:
bundle exec ruby starter.rb query initial-idThis will output Query result for id initial-id: pre-patch
This stage is for needing to run old and new workflows at the same time. To simulate our patched workflow, stop the worker from before and start it again with the patched workflow:
bundle exec ruby worker.rb patchedNow let's start another workflow with this patched code:
bundle exec ruby starter.rb start patched-idThis will output Started workflow with id patched-id-workflow-id.
Now query the old workflow that's still running:
bundle exec starter.rb query initial-idThis will output "Query result for id initial-id: pre-patch" since it is pre-patch.
But if we execute a query against the new code:
bundle exec starter.rb query patched-idWe get "Query result for id patched-id: post-patch".
This is how old workflow code can take old paths and new workflow code can take new paths.
Once we know that all workflows that started with the initial code from "Stage 1" are no longer running, we don't need the patch so we can deprecate it. To use the patch deprecated workflow, stop the worker from before and start it again with:
bundle exec ruby worker.rb deprecatedQuerying the initial workflow should error now.
bundle exec ruby starter.rb query initial-idThrows an error: [TMPRL1100] Nondeterminism error: Activity type of scheduled event 'PrePatch' does not match activity type of activity command 'PostPatch'
All workflows in "Stage 2" and any new workflows can be queried.
Now let's start another workflow with this patch deprecated code:
bundle exec ruby starter.rb start deprecated-idThis will output Started workflow with id deprecated-id.
Now query the patched workflow from "Stage 2"
bundle exec ruby starter.rb query patched-idThis will output "Query result for id patched-id: post-patch".
And if we execute a query against the latest workflow:
bundle exec ruby starter.rb query deprecated-idAs expected, this will output "Query result for id deprecated-id: post-patch".
Once we know we don't even have any workflows running on "Stage 2" or before (i.e. the workflow with the patch with both code paths), we can just remove the patch deprecation altogether. To use the patch complete workflow, stop the worker from before and start it again with:
bundle exec ruby worker.rb completeAll workflows in "Stage 3" and any new workflows will work. Now let's start another workflow with this patch complete code:
bundle exec ruby starter.rb start complete-idNow query the patch deprecated workflow that's still running:
bundle exec ruby starter.rb query deprecated-idThis will output "Query result for id deprecated-id: post-patch".
And if we execute a query against the latest workflow:
bundle exec ruby starter.rb query completed-idAs expected, this will output "Query result for id complete-id: post-patch".
Following these stages, we have successfully altered our workflow code.