任务编辑器¶
任务编辑器是位于 #/dag/<id>/task/<task_id> 的全页表单,用于配置 DAG 中的单个任务——包括命令、模板变量、项目代码、依赖关系和重试行为。与 cronova Web 控制台的其他页面一样,这里没有保存按钮:每次改动都会自动保存。

从 DAG 的 Structure 标签页(参见使用 DAG)即可进入任务编辑器——点击某个任务行,或新增一个任务。面包屑导航和 ← back 按钮可返回 DAG 页面。
任务 ID 与类型¶
| 字段 | 行为 |
|---|---|
| Task ID | 重命名在输入框失去焦点(blur)时生效,而非每次按键都触发。ID 必须非空、在 DAG 内唯一,并且匹配 [A-Za-z0-9][A-Za-z0-9_.-]*。无效或重复的 ID 会弹出警告 toast,输入框恢复为旧 ID。重命名成功后,所有指向旧 ID 的兄弟任务依赖也会被同步改写。 |
| Type | 取值为 shell、python、sql、jar、http 之一。切换类型会立即重新渲染下方对应类型的表单字段——已存储的命令会被保留,因此切回去不会丢失工作内容。 |
可视化命令编辑器¶
对于 shell、python 和 sql 任务(以及 http 任务的 URL/headers/body),命令字段是一个可视化模板编辑器。普通文本保持为普通文本,但每个 {{ name }} 模板变量都会渲染成带颜色的药丸——一个原子化的令牌,可以整体移动,但不会被逐字符误编辑。药丸颜色对应变量类别:
| 药丸类别 | 模式 | 含义 |
|---|---|---|
| 内置 | {{ logical_date }} 等 |
由调度器按运行注入的值 |
| 变量 | {{ var.KEY }} |
变量存储中的共享变量 |
| 连接 | {{ conn.id.field }} |
已存储连接的某个字段 |
| 参数 | {{ params.key }} |
手动触发时传入的参数 |
药丸的使用方式:
- 插入药丸:点击调色板中的芯片、把芯片拖入编辑器中的精确位置,或使用键盘——芯片可获得焦点,按 Enter / Space 在光标处插入。
- 移动药丸:在编辑器内把它拖到新位置;光标标记会显示落点。
- 删除药丸:点击其 × 按钮,或把光标放到旁边后按 Backspace / Del。
- 多行命令天然可用:Enter 插入换行,粘贴的代码会以纯文本插入并保留缩进。单行字段(如 HTTP URL)会把粘贴内容中的换行折叠为空格。
- 悬停在药丸上可查看提示,说明该变量会解析为什么值。
编辑器下方的 Will run: 预览显示实际存储的字符串——即你的命令加上高亮的字面 {{ }} 占位符。药丸只是一层视图;cronova 持久化并在运行时渲染的是那个纯模板字符串,与你在 DAG YAML 中手写的内容完全一致。
Tip
编辑器会把任何 {{ dotted.name }} 令牌药丸化——正好是调度器会替换的那一集合。如果你粘贴的命令已经包含模板占位符,它们会自动变成药丸。各变量的解析结果参见模板变量。
变量调色板¶
编辑器上方是一个分组的可插入变量调色板:
| 分组 | 内容 | 插入方式 |
|---|---|---|
| built-in | 六个运行变量:logical_date、logical_datetime、run_id、dag_id、task_id、try_number |
点击、拖拽或键盘 |
| variables | 变量存储中每个键对应一个芯片(var.KEY) |
点击、拖拽或键盘 |
| connections | 每个已存储连接对应一个芯片(conn.id) |
点击会打开字段菜单——选择 host、port、login 或 password 插入 {{ conn.id.field }}。拖拽芯片则插入 .host。 |
| params | 一个自由输入的键名输入框 | 输入键名(如 day)并按 Enter 插入 {{ params.day }} |
当尚无任何变量或连接时,对应分组会显示 set up 链接,直达 Resources 页面。这些值如何定义和注入,参见变量、连接与参数。
按类型渲染的表单¶
每种任务类型渲染各自的字段(完整细节见任务类型):
| 类型 | 字段 |
|---|---|
shell |
Command 药丸编辑器 + Will run: 预览,外加下方的 Project 区域。 |
python |
Python code 药丸编辑器。代码通过 python3 -c 内联执行;可从环境中读取 CRONOVA_* 变量,非零退出码即视为失败。 |
sql |
Connection——已配置连接的 id(其类型决定驱动:postgres/mysql/sqlite)——以及 SQL query 药丸编辑器。 |
jar |
结构化表单:Jar path、Main class(可选)、Arguments。表单会组装出 java -jar app.jar …(或 java -cp jar main …)并在 Will run: 预览中展示。edit raw command 链接是进入自由编辑的逃生舱;use form 可切回表单,但前提是原始命令仍能解析回表单结构。 |
http |
Method(GET/POST/PUT/PATCH/DELETE/HEAD)、URL、Headers(每行一条,格式为 Key: Value)、Body,以及 Expected status(逗号分隔,如 200,201;留空则接受任意 2xx)。URL、headers 和 body 都是药丸编辑器,因此 {{ var. }} 和 {{ conn. }} 在各处均可用。 |
项目(shell 任务)¶
shell 任务可以挂载一个已上传的项目——即包含脚本和数据文件的目录。Project 区域允许你从下拉框选择已有项目,或直接在编辑器内打开 Upload / new project 面板:
- Upload files / folder——选择文件、选择整个文件夹,或把文件/文件夹拖到拖放区。拖入
.zip会自动解压。 - Write a script——输入文件名(如
main.py)并内联填写内容,适合快速创建单文件项目。
为项目命名(字母、数字、. _ -)后点击 Upload;任务会自动指向该项目。运行时每次尝试都会获得一份全新的、隔离的项目副本作为工作目录,副本路径通过 CRONOVA_PROJECT_DIR 导出——完整的暂存模型参见运行你自己的脚本与项目。
Note
上传是增量式的:以相同名称重新上传会对文件做 upsert,因此推送一个改动的脚本不需要重传整个文件夹。正在运行的尝试会继续使用其启动时的副本;改动在下一次运行时生效。
依赖与触发规则¶
DAG 中的其他每个任务都会以芯片形式出现在 Depends on 下方——点击芯片即可切换其是否为本任务的上游。编辑器会拒绝任何会形成环的切换:芯片会弹回原状态,并出现 "Dependency cycle detected" toast,因为 DAG 必须保持无环。
Trigger rule 下拉框决定任务相对于其上游何时可以运行;所选规则的一行说明会显示在字段正下方:
| 规则 | 运行条件 |
|---|---|
all_success |
所有上游成功(默认) |
all_done |
所有上游结束,无论成功与否——适合清理/汇总任务 |
one_success |
任意一个上游成功 |
one_failed |
任意一个上游失败——适合告警任务 |
all_failed |
所有上游失败 |
none_failed |
没有上游失败(成功或跳过均可) |
实际示例参见依赖与触发规则。
高级选项¶
Advanced options 分组默认折叠,当其中任一值被设置时会自动展开:
| 字段 | 含义 |
|---|---|
| Pool | 命名的并发槽位,跨所有 DAG 共享;同一资源池中的任务竞争其槽位。资源池在管理页面中管理。 |
| Priority | 当任务争抢同一资源池时,优先级高的先运行。 |
| Retries | 失败后的重试次数;留空则继承 DAG 的默认重试次数。 |
| Retry delay (s) | 两次尝试之间等待的秒数;留空则继承默认值。 |
| Timeout (s) | 单次执行超过该秒数后强制终止。0 表示不限制。 |
| Task SLA (sec) | 从运行开始计时;任务未在规定时间内完成则告警。0 表示关闭。 |
调优指南见重试、超时与资源池。
自动保存¶
任务标题旁的徽标报告整个 DAG 的保存状态:
| 徽标 | 含义 |
|---|---|
| Saved | 所有内容已持久化。 |
| Saving… | 一次防抖保存正在进行中(编辑会在约半秒内被批量合并)。 |
| Fix errors to save | 校验失败——错误列在表单底部,修复之前不会写入任何内容。 |
| Save failed | 服务端拒绝了保存;徽标会显示错误信息。 |
校验涵盖:空或重复的任务 ID、空命令(非 HTTP 类型)、http 任务缺少 URL、sql 任务缺少连接,以及依赖环。
Warning
编辑一旦通过校验就会直接保存到线上 DAG——没有草稿模式。如果调度器在你编辑途中启动了一次运行,该运行使用的是最后一次保存的内容。
常见问题¶
保存按钮在哪里? 没有保存按钮。工作流调度器的 UI 会在每次有效改动后片刻自动保存整个 DAG——观察徽标从 Saving… 翻转为 Saved 即可。
如何在命令中使用密钥?
不要直接粘贴。把它存为连接或变量,然后插入 {{ conn.id.password }} 或 {{ var.KEY }} 药丸——值在运行时才会被替换,永远不会出现在 DAG 定义中。
可以手动输入 {{ }} 模板而不用药丸吗?
可以。药丸只是存储的模板字符串之上的一层可视化;任何粘贴或输入的、匹配 {{ name }} 的内容都会变成药丸,而 Will run: 预览始终显示实际存储的原始字符串。
为什么我的任务重命名没有生效? 重命名在失去焦点时生效——点击或用 Tab 移出 ID 输入框即可。如果新 ID 为空、无效或已被兄弟任务占用,编辑器会显示 toast 并保留旧 ID。