定时 Workflow
在 Workflow 上声明 schedule 字段,Mastra 就会按你指定的 cron 触发它。同一个 Workflow 仍可通过 workflow.start() 直接调用;定时触发和手动 Run 共用一条执行路径。
快速开始快速开始的直接链接
以下 Workflow 每天纽约时间上午 9 点运行。像其他 Workflow 一样将其注册到 Mastra,Scheduler 会自动发现它。
import { createWorkflow, createStep } from '@mastra/core/workflows'
import { z } from 'zod'
const sendReport = createStep({
id: 'send-report',
inputSchema: z.object({ userId: z.string() }),
outputSchema: z.object({ ok: z.boolean() }),
execute: async ({ inputData }) => {
// ...send the report for inputData.userId
return { ok: true }
},
})
export const dailyReport = createWorkflow({
id: 'daily-report',
inputSchema: z.object({ userId: z.string() }),
outputSchema: z.object({ ok: z.boolean() }),
schedule: {
cron: '0 9 * * *',
timezone: 'America/New_York',
inputData: { userId: 'system' },
},
})
.then(sendReport)
.commit()
不会再发生单独的“注册计划”调用。Mastra 启动时,Scheduler 会直接读取 Workflow 上的 schedule。
schedule 会改变什么what-schedule-changes的直接链接
声明 schedule 的 Workflow 会自动提升到事件驱动执行引擎。公共 API(workflow.start()、workflow.startAsync()、streamLegacy()、resume())保持不变;EventedWorkflow extends Workflow 并以相同签名覆盖每个方法。从代码角度看,定时触发与手动 Run 没有区别。
这种提升有一项实际影响:事件驱动 Run 需要支持并发更新的 Storage Adapter,例如 @mastra/libsql。如果 Adapter 不支持,createRun() 会抛出明确错误并指向 schedule 字段。请更换 Adapter 或移除计划。
单个计划单个计划的直接链接
对于只按一种周期触发的 Workflow,请向 schedule 传入对象:
const dailyReport = createWorkflow({
id: 'daily-report',
schedule: {
cron: '0 9 * * *',
timezone: 'America/New_York',
inputData: { userId: 'system' },
},
// ...
})
字段:
cron(必填):由 5、6 或 7 部分组成的 cron 表达式。在构造 Workflow 时验证。timezone(可选):IANA 时区,例如America/New_York。默认为宿主的本地时区。生产环境请显式设置,避免触发时间依赖 Server Locale。inputData(可选):每次触发时作为 Workflow 输入传入的载荷。initialState(可选):Run 的初始状态。requestContext(可选):附加到 Run 的 Request Context。metadata(可选):与计划行一同持久化的任意元数据。
多个计划多个计划的直接链接
传入数组,可以按多个周期触发同一个 Workflow。每个条目都需要唯一且稳定的 id:
const statusCheck = createWorkflow({
id: 'status-check',
schedule: [
{ id: 'morning', cron: '0 9 * * *', inputData: { window: 'morning' } },
{ id: 'evening', cron: '0 18 * * *', inputData: { window: 'evening' } },
],
// ...
})
每个条目都会创建独立的计划行,按各自 cron 触发,并在 Studio Schedules 视图中单独显示。
在 Studio 中查看计划在 Studio 中查看计划的直接链接
Studio 将计划显示为顶层区域,而不是 Workflow 内的选项卡:
- 所有计划:打开
/workflows/schedules查看跨 Workflow 列表。每行显示 Workflow ID、cron、下次触发时间和最近 Run 的状态,因此可以一眼看出“是否有故障”。 - 按 Workflow 筛选:追加
?workflowId=<id>,将列表限定为单个 Workflow,例如/workflows/schedules?workflowId=daily-report。 - 计划详情:选择任意行,打开
/workflows/schedules/:scheduleId。页面显示计划元数据和 Pause / Resume 控件,随后是完整触发历史。
如果 Workflow 至少有一个计划,其标题区会包含 Schedules 操作:
- 只有一个匹配计划时,操作会直接链接到详情页。
- 有多个计划时,操作链接到
/workflows/schedules?workflowId=<id>的 Workflow 筛选列表。 - 没有计划时,操作隐藏。
触发历史触发历史的直接链接
每次触发都会记录一行,其中包含 Run ID、计划时间、实际触发时间和发布状态。计划详情页会将每次触发与对应 Workflow Run 连接,并显示:
- Run 状态(
running、success、failed、suspended、canceled)徽章。 - Run 的开始时间和持续时长。
- 指向
/workflows/:workflowId/graph/:runId完整 Run 图视图的链接。 - 对于因触发发布与 Run Snapshot 之间存在竞态而尚未写入 Run 记录的触发,显示
pending徽章。 - Scheduler 完全无法将 Run 加入队列时,显示带发布错误的
publish failed徽章。
非终止状态的触发会使面板每 5 秒轮询一次,直到达到终止状态。列表支持分页,因此长期运行的计划不会一次加载数千行。
在运行时暂停计划在运行时暂停计划的直接链接
定时 Workflow 在生产环境错误触发时,无需重新部署或手动编辑数据库。可通过 SDK 暂停:
import { MastraClient } from '@mastra/client-js'
const client = new MastraClient({ baseUrl: 'http://localhost:4111' })
// Schedule ids are derived from the workflow id: `wf_<workflowId>` for a
// single declarative schedule, or `wf_<workflowId>__<scheduleId>` when you
// declare multiple schedules per workflow as an array.
await client.pauseSchedule('wf_daily-report')
// ...investigate, ship a fix, then:
await client.resumeSchedule('wf_daily-report')
在 Studio 中打开计划详情页,然后选择标题区的 Pause 或 Resume。
需要了解的规则:
- 暂停是持久的。状态会写入 schedules 表,并在进程重启和重新部署后继续保留。即使更改
cron、timezone或其他字段,声明式配置 Upsert 也绝不会覆盖用户设置的状态。 - 恢复会从当前时间重新计算
nextFireAt。暂停一周的计划不会在恢复时立即触发积压的 7 次 Run,而会在下一个正常 cron 时间点触发。 - 使用
resumeSchedule或 Studio 的 Resume 按钮取消暂停。编辑 Workflow 的schedule配置不会取消已暂停行。 - 暂停和恢复具有幂等性。对已暂停计划调用暂停不会产生任何操作。
- 此运行时覆盖控制现有计划。声明式计划应在代码中编写,通过
createWorkflow的schedule字段创建、删除和编辑。要在运行时以命令式方式创建计划,请使用统一的mastra.schedules服务并提供workflowId。
底层 HTTP 路由为 POST /api/schedules/:scheduleId/pause 和 POST /api/schedules/:scheduleId/resume,两者都需要 schedules:write 权限。
重新部署更改重新部署更改的直接链接
更改 schedule 配置并重新部署时,Mastra 会比较现有计划行与新配置:
- 如果
cron或timezone发生变化,会重新计算nextFireAt。 - 如果只有
inputData、initialState或metadata发生变化,会原地修补计划行并保留下次触发时间。 - 用户设置的状态(例如通过
client.pauseSchedule暂停)和触发历史绝不会被覆盖。
从 Workflow 的 schedule 数组中移除计划条目后,下次启动时会删除对应行。
部署拓扑部署拓扑的直接链接
内置 Scheduler 使用 setInterval tick 循环轮询 schedules 表并认领到期行,再通过进程内 PubSub 分发 Workflow Run。它假定宿主进程长期运行。
长期运行的宿主(推荐)长期运行的宿主(推荐)的直接链接
Fly Machines、Railway、Render、AWS ECS、GKE 或你自己的 Server 等部署目标会在 cron tick 之间保持 Mastra 进程活动,计划无需额外设置即可运行。生产部署可将 Scheduler 作为专用 Worker 进程运行,使其与 API 层隔离。
Serverless 平台Serverless 平台的直接链接
Vercel、Netlify、AWS Lambda 和 Cloudflare Workers 等函数即服务平台会在每次请求后关闭进程。由于 tick 循环不会迎来第二个 tick,目前在这些平台上,代码中声明的计划无法通过内置 Scheduler 触发。
请在这些平台上改用 @mastra/inngest。Inngest 原生支持 Serverless,并会替你保存 cron 状态。
Inngest WorkflowInngest Workflow的直接链接
本页所述 schedule 字段驱动 Mastra 内置 Scheduler。使用 @mastra/inngest 时,定时 Workflow 通过 createFunction 上 Inngest 自己的 cron 字段配置,并由 Inngest Scheduler 触发。
实际影响:
- Inngest 计划不会出现在 Studio 的
/workflows/schedules视图中。 - Inngest Workflow 的标题区不会显示 Schedules 操作。
client.pauseSchedule和client.resumeSchedule无法控制 Inngest 计划。
请从 Inngest Dashboard 管理 Inngest 计划。如果希望由 Mastra 端到端负责计划,请使用 Mastra 计划。
相关内容相关内容的直接链接
- Workflow 概览
- 挂起与恢复
- Worker:Scheduler Worker在专用进程中运行 cron 计划
- Agent 计划:按 cron 计划运行 Agent 而不是 Workflow,并通过
mastra.schedules在运行时管理两类计划。