4.4 - 取消

可以通过以下方式中断工作流执行:

终止工作流强制停止工作流执行。此操作类似于杀死进程。

在大多数情况下,取消是更可取的方式,因为它允许工作流优雅地完成。仅当工作流卡住且无法正常取消时,才应使用终止。


取消工作流执行

取消工作流优雅地停止工作流执行。此操作类似于向进程发送 SIGTERM 信号。

要在 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() 实际上就是请求取消该任务。


终止工作流执行

终止操作强制停止工作流执行,类似于杀死进程。

要在 Python 中终止工作流执行,需对工作流句柄调用 terminate() 函数。

await client.get_workflow_handle("your_workflow_id").terminate()

重置工作流执行

重置工作流执行将终止当前工作流执行,从在其事件历史中指定的点启动新工作流执行。当工作流因非确定性错误或其他问题导致无法完成而阻塞时,可使用重置操作。

重置工作流时,事件历史中截至重置点之前的部分被复制到新工作流执行中,工作流将从该点开始使用当前代码继续执行。重置操作仅在底层问题已修复的情况下才有效,比如移除非确定性代码。重置点之后的所有执行进度都将被丢弃。重置时需提供原因,该原因将被记录到事件历史中。

Web UI

  1. 导航到工作流执行详情页面。
  1. 点击右上角下拉菜单中的“Reset”按钮。
  1. 选择要重置到的事件 ID。
  1. 提供原因。
  1. 确认重置。

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

重置后,监控新工作流执行,确保其成功完成。