4.7 - 调度
调度工作流
工作流调度是自动化流程中的关键环节,在处理对时间敏感的任务时尤为重要。通过调度工作流,可以实现重复性任务的自动化,减少人工干预的需求,确保业务流程的及时执行。
可以使用以下操作调度工作流执行,从而掌控自动化流程。
调度的行为由其重叠策略(Overlap Policy)决定。如果调度启动的工作流执行处于暂停(Paused)状态,该执行将保持开启,并且在进行重叠决策时被计为正在运行中的执行。
创建调度工作流
创建操作用于新建调度。创建新调度时,系统生成唯一的调度 ID,可以在其他调度命令中使用该 ID 引用此调度。
要在 Python 中创建调度工作流执行,需使用客户端的 create_schedule() 异步方法。将调度 ID 和调度对象传递给该方法,即可创建调度工作流执行。将 action 参数设置为 ScheduleActionStartWorkflow ,启动工作流执行。还可以选择将 spec 参数设置为 ScheduleSpec ,指定调度计划,或将 intervals 参数设置为 ScheduleIntervalSpec,指定时间间隔。其他可用选项包括:cron_expressions、skip、start_at 和 jitter。
import asyncio
from datetime import timedelta
from temporalio.client import (
Client,
Schedule,
ScheduleActionStartWorkflow,
ScheduleIntervalSpec,
ScheduleSpec,
ScheduleState,
)
from your_workflows import YourSchedulesWorkflow
async def main():
client = await Client.connect("localhost:7233")
await client.create_schedule(
"workflow-schedule-id",
Schedule(
action=ScheduleActionStartWorkflow(
YourSchedulesWorkflow.run,
"my schedule arg",
id="schedules-workflow-id",
task_queue="schedules-task-queue",
),
spec=ScheduleSpec(
intervals=[ScheduleIntervalSpec(every=timedelta(minutes=2))]
),
state=ScheduleState(note="Here's a note on my Schedule."),
),
)
if __name__ == "__main__":
asyncio.run(main())调度自动删除当调度完成其所有工作流执行的创建后,Temporal 服务会将其删除,因为该调度不再触发新执行。Temporal 服务不保证此删除操作的具体发生时间。
回填调度工作流
回填操作执行规定时间范围之前的操作。当需要执行错过的或延迟的操作,或者希望测试调度时间之前的工作流时,此命令非常有用。
要在 Python 中对调度工作流执行进行回填,需要使用调度句柄的 backfill() 异步方法。
import asyncio
from datetime import datetime, timedelta
from temporalio.client import Client, ScheduleBackfill, ScheduleOverlapPolicy
async def main():
client = await Client.connect("localhost:7233")
handle = client.get_schedule_handle(
"workflow-schedule-id",
)
now = datetime.utcnow()
(
await handle.backfill(
ScheduleBackfill(
start_at=now - timedelta(minutes=10),
end_at=now - timedelta(minutes=9),
overlap=ScheduleOverlapPolicy.ALLOW_ALL,
),
),
)
print(f"Result: {handle}")
if __name__ == "__main__":
asyncio.run(main())删除调度工作流
删除操作用于删除调度。删除调度不会影响该调度已启动的工作流。
要在 Python 中删除调度工作流执行,需要使用调度句柄的 delete() 异步方法。
import asyncio
from temporalio.client import Client
async def main():
client = await Client.connect("localhost:7233")
handle = client.get_schedule_handle(
"workflow-schedule-id",
)
await handle.delete()
if __name__ == "__main__":
asyncio.run(main())描述调度工作流
描述操作用于查看当前调度的配置,包括过去、当前和未来的工作流运行(Workflow Run)的相关信息。当需要获取调度及其关联工作流运行的详细视图时,此命令非常有用。
要在 Python 中描述调度工作流执行,需要使用调度句柄的 describe() 异步方法。可以从 ScheduleDescription 类中获取调度工作流执行的完整属性列表。
import asyncio
from temporalio.client import Client
async def main():
client = await Client.connect("localhost:7233")
handle = client.get_schedule_handle(
"workflow-schedule-id",
)
desc =await handle.describe()
print(f"Returns the note:{desc.schedule.state.note}")
if __name__ == "__main__":
asyncio.run(main())列出调度工作流
列表操作用于列出所有可用的调度。当需要查看所有调度及其对应的调度 ID 时,此命令非常有用。
要列出所有调度,需要使用客户端的 list_schedules() 异步方法。如果添加或删除调度,这些调度无法立即在列表中反映出来。
import asyncio
from temporalio.client import Client
async def main() -> None:
client = await Client.connect("localhost:7233")
asyncfor scheduleinawait client.list_schedules():
print(f"List Schedule Info: {schedule.info}.")
if __name__ == "__main__":
asyncio.run(main())暂停调度工作流
暂停操作用于暂停和恢复调度。暂停调度时,与该调度关联的所有未来工作流运行都将被暂时停止。当因维护或其他原因需要暂时中止工作流时,此命令非常有用。
要在 Python 中暂停调度工作流执行,需要使用调度句柄的 pause() 异步方法。可以通过向 pause() 方法传入备注,说明暂停调度的原因。
import asyncio
from temporalio.client import Client
async def main():
client = await Client.connect("localhost:7233")
handle = client.get_schedule_handle(
"workflow-schedule-id",
)
await handle.pause(note="Pausing the schedule for now")
if __name__ == "__main__":
asyncio.run(main())触发调度工作流
触发操作用于立即执行与给定调度对应的操作。默认情况下,此操作受调度的重叠策略约束。当需要在调度时间之外执行工作流时,此命令非常有用。
要在 Python 中触发调度工作流执行,需要使用调度句柄的 trigger() 异步方法。
import asyncio
from temporalio.client import Client
async def main():
client = await Client.connect("localhost:7233")
handle = client.get_schedule_handle(
"workflow-schedule-id",
)
await handle.trigger()
if __name__ == "__main__":
asyncio.run(main())更新调度工作流
更新操作用于更新现有调度。当需要修改调度的配置(比如变更开始时间、结束时间或时间间隔)时,此命令非常有用。
创建接收 ScheduleUpdateInput,返回 ScheduleUpdate 的函数。若要更新调度,则需要使用回调函数根据当前描述,构建更新。下面的示例使用新参数更新调度。
import asyncio
from temporalio.client import (
Client,
ScheduleActionStartWorkflow,
ScheduleUpdate,
ScheduleUpdateInput,
)
async def main():
client = await Client.connect("localhost:7233")
handle = client.get_schedule_handle(
"workflow-schedule-id",
)
async def update_schedule_simple(input: ScheduleUpdateInput) -> ScheduleUpdate:
schedule_action = input.description.schedule.action
if isinstance(schedule_action, ScheduleActionStartWorkflow):
schedule_action.args = ["my new schedule arg"]
return ScheduleUpdate(schedule=input.description.schedule)
await handle.update(update_schedule_simple)
if __name__ == "__main__":
asyncio.run(main())延迟开始
使用 start_delay 可以在未来的特定时间点调度一次性的工作流执行。
在客户端的 start_workflow() 或 execute_workflow() 异步方法中使用 start_delay 选项。
async def main():
client = await Client.connect("localhost:7233")
result = await client.execute_workflow(
YourWorkflow.run,
"your name",
id="your-workflow-id",
task_queue="your-task-queue",
start_delay=timedelta(hours=1, minutes=20, seconds=30)
)
print(f"Result: {result}")
if __name__ == "__main__":
asyncio.run(main())