升级正在运行的工作流程的推荐做法是什么?
如果已经使用先前的工作流程实现创建了正在运行的执行,则进行任何代码更改或更新工作流程逻辑都会导致Cadence出现“非确定性错误”,因为它无法使用更新的实现来重放现有工作流程执行的历史记录。 >
在不中断现有工作流程执行的情况下,有哪些应对升级的策略?
答案 0 :(得分:0)
GetVersion用于安全地对工作流程定义执行向后不兼容的更改。在有工作流运行时,不允许更新工作流代码,因为这将破坏确定性。解决方案是既有用于重播现有工作流程的旧代码,又有第一次执行时使用的新代码。首次执行时,GetVersion
返回maxSupported
版本。此版本作为标记事件记录在工作流历史记录中。即使maxSupported
版本已更改,也会在重播时返回记录的版本。 DefaultVersion
常量包含以前未版本化的代码版本。例如,最初的工作流程具有以下代码:
err = cadence.ExecuteActivity(ctx, foo).Get(ctx, nil)
它应该更新为
err = cadence.ExecuteActivity(ctx, bar).Get(ctx, nil)
执行更新的向后兼容方式是
v := GetVersion(ctx, "fooChange", DefaultVersion, 1)
if v == DefaultVersion {
err = cadence.ExecuteActivity(ctx, foo).Get(ctx, nil)
} else {
err = cadence.ExecuteActivity(ctx, bar).Get(ctx, nil)
}
然后必须将栏更改为baz:
v := GetVersion(ctx, "fooChange", DefaultVersion, 2)
if v == DefaultVersion {
err = cadence.ExecuteActivity(ctx, foo).Get(ctx, nil)
} else if v == 1 {
err = cadence.ExecuteActivity(ctx, bar).Get(ctx, nil)
} else {
err = cadence.ExecuteActivity(ctx, baz).Get(ctx, nil)
}
以后,当没有工作流运行DefaultVersion时,可以删除相应的分支:
v := GetVersion(ctx, "fooChange", 1, 2)
if v == 1 {
err = cadence.ExecuteActivity(ctx, bar).Get(ctx, nil)
} else {
err = cadence.ExecuteActivity(ctx, baz).Get(ctx, nil)
}
在引入GetVersion调用之后,目前尚不支持将其完全删除的方法。即使只剩下一个分支也要保留它:
GetVersion(ctx, "fooChange", 2, 2)
err = cadence.ExecuteActivity(ctx, baz).Get(ctx, nil)
GetVersion
必须根据工作流程历史记录对版本进行验证,如果工作流程代码与此版本不兼容,则决策失败。
Java具有类似的Workflow.getVersion API。