4.4 - 取消
可以通过以下方式中断工作流执行:
- 取消(Cancel):取消操作优雅地停止工作流执行。
- 终止(Terminate):终止操作强制停止工作流执行。
终止工作流强制停止工作流执行。此操作类似于杀死进程。
- 系统在事件历史中记录
WorkflowExecutionTerminated事件。
- 终止操作强制且立即停止工作流执行。
- 工作流代码没有机处理终止操作。
- 不会调度工作流任务。
在大多数情况下,取消是更可取的方式,因为它允许工作流优雅地完成。仅当工作流卡住且无法正常取消时,才应使用终止。
取消工作流执行
取消工作流优雅地停止工作流执行。此操作类似于向进程发送 SIGTERM 信号。
- 系统在事件历史中记录
WorkflowExecutionCancelRequested事件。
- 系统调度工作流任务,处理取消请求。
- 工作流代码可以处理取消操作,执行清理逻辑。
- 系统不会强制停止工作流。
要在 Python 中取消工作流执行,需要对工作流句柄使用 cancel() 函数。
await client.get_workflow_handle("your_workflow_id").cancel()从工作流中取消 Activity
从工作流内部取消 Activity,要求 Activity 执行发送心跳,并且设置心跳超时。如果未调用心跳,则 Activity 无法接收取消请求。在执行非即时完成的 Activity 时,Activity 执行都应发送心跳且设置心跳超时,确保服务端知道它仍在工作。
取消 Activity 时,将在下个可用的执行时机抛出错误。如果需要执行清理逻辑,可以在 finally 子句中处理,或者在捕获取消错误后进行相应处理。为让 Activity 最终显示为已取消状态,必须重新抛出该异常。
与常规 Activity 不同,本地 Activity(Local Activity)即使不发送心跳也可取消。本地 Activity 在本地进行处理,处理取消逻辑所需的所有信息都在同一 Worker 进程中。
要从工作流执行中取消 Activity,请对 start_activity() 返回的 Activity 句柄调用 cancel() 方法。
@activity.defn
async def cancellable_activity(input: ComposeArgsInput) -> NoReturn:
try:
while True:
print("Heartbeating cancel activity")
await asyncio.sleep(0.5)
activity.heartbeat("some details")
except asyncio.CancelledError:
print("Activity cancelled")
raise
@activity.defn
async def run_activity(input: ComposeArgsInput):
print("Executing activity")
return input.arg1 + input.arg2
@workflow.defn
class GreetingWorkflow:
@workflow.run
async def run(self, input: ComposeArgsInput) -> None:
activity_handle = workflow.start_activity(
cancellable_activity,
ComposeArgsInput(input.arg1, input.arg2),
start_to_close_timeout=timedelta(minutes=5),
heartbeat_timeout=timedelta(seconds=30),
)
await asyncio.sleep(3)
activity_handle.cancel()Activity 句柄是 Python 中的任务。调用 cancel() 实际上就是请求取消该任务。
终止工作流执行
终止操作强制停止工作流执行,类似于杀死进程。
- 系统在事件历史中记录
WorkflowExecutionTerminated事件。
- 终止操作强制且立即停止工作流执行。
- 工作流代码没有机会处理终止操作。
- 不会调度工作流任务。
要在 Python 中终止工作流执行,需对工作流句柄调用 terminate() 函数。
await client.get_workflow_handle("your_workflow_id").terminate()重置工作流执行
重置工作流执行将终止当前工作流执行,从在其事件历史中指定的点启动新工作流执行。当工作流因非确定性错误或其他问题导致无法完成而阻塞时,可使用重置操作。
重置工作流时,事件历史中截至重置点之前的部分被复制到新工作流执行中,工作流将从该点开始使用当前代码继续执行。重置操作仅在底层问题已修复的情况下才有效,比如移除非确定性代码。重置点之后的所有执行进度都将被丢弃。重置时需提供原因,该原因将被记录到事件历史中。
Web UI
- 导航到工作流执行详情页面。
- 点击右上角下拉菜单中的“Reset”按钮。
- 选择要重置到的事件 ID。
- 提供原因。
- 确认重置。
Web UI 显示可用重置点,在重置完成后生成指向新工作流执行的链接。
Temporal CLI
使用 temporal workflow reset 命令重置工作流执行:
temporal workflow reset \
--workflow-id <workflow-id> \
--event-id <event-id> \
--reason "Reason for reset"比如:
temporal workflow reset \
--workflow-id my-background-check \
--event-id 4 \
--reason "Fixed non-deterministic code"默认情况下,该命令重置默认命名空间中的最新工作流执行。使用 --run-id 可重置特定的运行。使用 --namespace 可指定不同的命名空间:
temporal workflow reset \
--workflow-id my-background-check \
--event-id 4 \
--reason "Fixed non-deterministic code" \
--namespace my-namespace \
--tls-cert-path /path/to/cert.pem \
--tls-key-path /path/to/key.pem重置后,监控新工作流执行,确保其成功完成。