6 - 运行 Worker

本节介绍由开发者自己托管,作为持久进程长期运行的 Worker。


创建及运行 Worker

使用 Temporal 客户端、要轮询的任务队列以及其可以执行的工作流和 Activity 创建 Worker。调用 run() 开始轮询。

client = await Client.connect("localhost:7233")

worker = Worker(
    client,
    task_queue="my-task-queue",
    workflows=[HelloWorkflow],
    activities=[some_activity],
)
await worker.run()

run() 不会自行返回。它一直轮询,直到调用 shutdown(),然后在关闭完成后返回。Worker 也是异步上下文管理器:async with worker 在进入时启动 Worker,在退出时将其关闭。


注册工作流和 Activity

所有轮询同一任务队列的 Worker 必须注册相同的工作流类型和 Activity 类型。任务队列不会按类型进行路由,因此轮询该队列的任何 Worker 都可能收到该队列上的任何任务。如果 Worker 收到它未注册的类型的任务,该任务将失败。

在 workflows 参数中传入工作流列表,在 activities 参数中传入 Activity 列表,也可以两者都传。

使用 async def 定义的 Activity 将在 Worker 的事件循环上运行。使用普通 def 定义的 Activity 是同步的,需要执行器,因此需要通过 activity_executor 参数传入执行器:

worker = Worker(
    client,
    task_queue="my-task-queue",
    workflows=[MyWorkflow],
    activities=[my_sync_activity],
    activity_executor=ThreadPoolExecutor(5),
)

同一个执行器可以在多个 Worker 之间共享。


配置 Worker 选项

Worker 构造函数接收关键字参数,用于控制并发限制、轮询器、超时时间和缓存等,其中包括 max_concurrent_activities、max_concurrent_workflow_tasks 和 max_cached_workflows。默认设置在大多数情况下都能正常工作。


运行版本化 Worker

在 deployment_config 中设置 Worker 的部署版本,启用版本管理,然后为 Worker 上的工作流设置默认版本行为。

worker = Worker(
    client,
    task_queue="my-task-queue",
    workflows=[HelloWorkflow],
    activities=[some_activity],
    deployment_config=WorkerDeploymentConfig(
        version=WorkerDeploymentVersion(
            deployment_name="my-app",
            build_id="1.0",
        ),
        use_worker_versioning=True,
        default_versioning_behavior=VersioningBehavior.PINNED,
    ),
)

若要在每个工作流上设置行为,而不是在 Worker 上设置,请将 versioning_behavior 参数传递给 @workflow.defn。


关闭 Worker

通过退出 async with 代码块,关闭 Worker,该代码块将调用 shutdown()。如果要使 Worker 持续运行直到进程被中断,那么创建 asyncio.Event,并且在代码块内等待该事件。

在捕获 KeyboardInterrupt 的入口点处设置事件:

interrupt_event = asyncio.Event()

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    try:
        loop.run_until_complete(main())
    except KeyboardInterrupt:
        interrupt_event.set()
        loop.run_until_complete(loop.shutdown_asyncgens())

在代码块内等待 interrupt_event 将使 Worker 保持运行状态。一旦事件被设置,代码块退出,Worker 将停止轮询新任务,等待正在执行中的任务完成,最长等待时间为 graceful_shutdown_timeout。

worker = Worker(
    client,
    task_queue="my-task-queue",
    workflows=[HelloWorkflow],
    activities=[some_activity],
    graceful_shutdown_timeout=timedelta(seconds=30),
)
async with worker:
    await interrupt_event.wait()