跳转到主要内容

概述

Shannon 使用 Temporal 的原生 Schedule API 支持定期任务执行。创建基于 cron 的调度,在指定间隔自动执行任务。

功能特性

  • 基于 Cron 的调度,支持时区设置
  • 资源限制,防止滥用
  • 预算控制,每次执行独立计费
  • 执行历史,带成本追踪
  • 暂停/恢复/删除操作
  • 多租户隔离,用户/租户所有权

创建调度

创建新的定期任务调度。
curl -X POST http://localhost:8080/api/v1/schedules \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "每日摘要",
    "description": "生成每日活动摘要",
    "cron_expression": "0 9 * * *",
    "timezone": "Asia/Shanghai",
    "task_query": "总结昨天的活动",
    "task_context": {
      "report_format": "markdown"
    },
    "max_budget_per_run_usd": 5.0,
    "timeout_seconds": 600
  }'

请求体

字段类型必填描述
namestring调度名称(最多 255 字符)
descriptionstring可选描述
cron_expressionstringCron 调度(5 字段格式)
timezonestringIANA 时区(默认:UTC)
task_querystring要执行的查询
task_contextobject任务的附加上下文
max_budget_per_run_usdnumber每次执行的最大预算(默认:10.0)
timeout_secondsinteger执行超时(默认:600)

响应

{
  "schedule_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "Schedule created successfully",
  "next_run_at": "2025-12-16T09:00:00+08:00"
}

列出调度

列出调度,支持分页和过滤。
curl "http://localhost:8080/api/v1/schedules?page=1&page_size=50&status=ACTIVE" \
  -H "Authorization: Bearer <token>"

查询参数

参数类型默认值描述
pageinteger1页码
page_sizeinteger50每页条数(最大 100)
statusstring-按状态过滤(ACTIVE, PAUSED)

响应

{
  "schedules": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "每日摘要",
      "cron_expression": "0 9 * * *",
      "timezone": "Asia/Shanghai",
      "status": "ACTIVE",
      "next_run_at": "2025-12-16T09:00:00+08:00",
      "total_runs": 45,
      "successful_runs": 43,
      "failed_runs": 2
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 50
}

获取调度详情

获取特定调度的详细信息。
curl "http://localhost:8080/api/v1/schedules/{id}" \
  -H "Authorization: Bearer <token>"

响应

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "每日摘要",
  "description": "生成每日活动摘要",
  "cron_expression": "0 9 * * *",
  "timezone": "Asia/Shanghai",
  "task_query": "总结昨天的活动",
  "task_context": {"report_format": "markdown"},
  "max_budget_per_run_usd": 5.0,
  "timeout_seconds": 600,
  "status": "ACTIVE",
  "created_at": "2025-01-01T00:00:00Z",
  "updated_at": "2025-01-15T10:00:00Z",
  "next_run_at": "2025-01-16T09:00:00+08:00",
  "last_run_at": "2025-01-15T09:00:00+08:00",
  "total_runs": 45,
  "successful_runs": 43,
  "failed_runs": 2
}

更新调度

更新现有调度。
curl -X PUT "http://localhost:8080/api/v1/schedules/{id}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "cron_expression": "0 10 * * *",
    "max_budget_per_run_usd": 8.0
  }'

请求体

所有字段均为可选。仅更新提供的字段。
字段类型描述
namestring新调度名称
descriptionstring新描述
cron_expressionstring新 cron 调度
timezonestring新时区
task_querystring新任务查询
task_contextobject新上下文
max_budget_per_run_usdnumber新预算限制
timeout_secondsinteger新超时时间

获取执行历史

获取调度的执行历史。
curl "http://localhost:8080/api/v1/schedules/{id}/runs?page=1&page_size=20" \
  -H "Authorization: Bearer <token>"

响应

{
  "runs": [
    {
      "workflow_id": "wf-abc-123",
      "query": "生成每日报告",
      "status": "COMPLETED",
      "result": "报告生成成功...",
      "model_used": "gpt-4o",
      "provider": "openai",
      "total_tokens": 12500,
      "total_cost_usd": 0.45,
      "duration_ms": 150000,
      "triggered_at": "2025-01-15T09:00:00Z",
      "started_at": "2025-01-15T09:00:01Z",
      "completed_at": "2025-01-15T09:02:30Z"
    }
  ],
  "total_count": 45,
  "page": 1,
  "page_size": 20
}

响应字段

字段类型描述
runsarray调度执行记录列表
runs[].workflow_idstring此次执行的工作流 ID
runs[].querystring执行的查询
runs[].statusstring执行状态(如 COMPLETED、FAILED)
runs[].resultstring执行结果(为空时省略)
runs[].error_messagestring失败时的错误信息(为空时省略)
runs[].model_usedstring使用的 LLM 模型(为空时省略)
runs[].providerstringLLM 提供商(为空时省略)
runs[].total_tokensinteger消耗的总 token 数
runs[].total_cost_usdnumber总费用(美元)
runs[].duration_msinteger执行时长(毫秒,为空时省略)
runs[].triggered_atstring触发时间(ISO 8601)
runs[].started_atstring开始执行时间(为空时省略)
runs[].completed_atstring执行完成时间(为空时省略)
total_countinteger执行记录总数
pageinteger当前页码
page_sizeinteger每页条数

暂停调度

暂停调度以停止后续执行。
curl -X POST "http://localhost:8080/api/v1/schedules/{id}/pause" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"reason": "临时维护"}'

响应

{
  "message": "Schedule paused successfully",
  "paused_at": "2025-01-15T10:00:00Z"
}

恢复调度

恢复已暂停的调度。
curl -X POST "http://localhost:8080/api/v1/schedules/{id}/resume" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"reason": "维护完成"}'

响应

{
  "message": "Schedule resumed successfully",
  "next_run_at": "2025-01-16T09:00:00+08:00"
}

删除调度

永久删除调度。
curl -X DELETE "http://localhost:8080/api/v1/schedules/{id}" \
  -H "Authorization: Bearer <token>"

响应

{
  "message": "Schedule deleted successfully"
}

Cron 表达式格式

使用标准 cron 语法(5 个字段):
┌───────────── 分钟 (0 - 59)
│ ┌───────────── 小时 (0 - 23)
│ │ ┌───────────── 日期 (1 - 31)
│ │ │ ┌───────────── 月份 (1 - 12)
│ │ │ │ ┌───────────── 星期 (0 - 6)(周日到周六)
│ │ │ │ │
* * * * *

常用示例

表达式描述
0 9 * * *每天上午 9:00
0 */4 * * *每 4 小时
0 0 * * 1每周一午夜
30 8 1 * *每月 1 日上午 8:30
0 12 * * 1-5工作日中午
0 0 1,15 * *每月 1 日和 15 日

资源限制

Shannon 强制执行资源限制以防止滥用:
限制默认值环境变量
每用户最大调度数50SCHEDULE_MAX_PER_USER
最小间隔60 分钟SCHEDULE_MIN_INTERVAL_MINS
每次运行最大预算$10.00SCHEDULE_MAX_BUDGET_USD
超出预算限制的调度将自动暂停。

错误响应

状态码错误描述
400Invalid cron expressionCron 语法错误
400Interval too short低于最小间隔
403Schedule limit reached超出每用户最大调度数
404Schedule not found无效的调度 ID
409Schedule already paused无法暂停已暂停的调度

下一步