后台任务
尚未发布后台任务是一个在 Extension 打开期间持续运行的函数,比如每 15 分钟同步一次。它需要 dozin.capabilities 里有 service。用 api.registerService(definition) 注册它。
ServiceDefinition
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 否 | 默认为包名。小写字母、数字和连字符。每个 Extension 最多 8 个 |
name | string | 否 | 显示在 设置 › 扩展 里,1–80 个字符;默认为 id |
start | 'auto' | 'manual' | 否 | 默认 manual。auto 在 secrets 都填好后随 Extension 一起启动。以用户的选择为准 |
restart | { policy?, maxRetries?, backoffSeconds? } | 否 | policy:never、on-failure(默认)或 always;maxRetries 0–100(默认 5);backoffSeconds 1–10 次等待,每次 1–3600 秒(默认 5、30、120) |
stopTimeoutSeconds | number | 否 | 1–30,默认 10:停止 等待 run 返回的时间 |
run(ctx) | function | 是 | 见下文 |
任何字段无效都会拒绝整个任务(registerService 抛出 TypeError);不会替你自动修正。
run(ctx) 尚未发布
任务本身。一直运行,直到 ctx.signal 触发。
| 名称 | 类型 | 说明 |
|---|---|---|
ctx | ServiceContext | 下面的字段和函数 |
返回 Promise<void>。返回即结束这次运行。抛出异常算作失败,按 restart 重试。按下 停止 后,如果 run 在 stopTimeoutSeconds 内没有返回,Extension 的进程会被重启。
ServiceContext 字段
| 字段 | 类型 | 说明 |
|---|---|---|
serviceId | string | 任务的键:包名,或 <package>.<id> |
runId | string | 这次运行 |
signal | AbortSignal | 在 停止、重启、关闭 Extension、卸载和退出 Cowork 时触发。每次请求前检查它 |
env | Readonly<Record<string, string>> | dozin.secrets 的值。缺少某个值的任务不会启动,并显示“缺少配置” |
dataDir | string | Extension 自己的数据文件夹,也是它的工作文件夹 |
ctx.status(text, level?, progress?) 尚未发布
设置显示在 设置 › 扩展 里该任务下面的那一行。
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
text | string | 是 | 这一行;最多保留 300 个字符 |
level | 'info' | 'warn' | 'error' | 否 | 默认 info |
progress | { done: number, total: number } | 否 | 显示为进度 |
无返回值。dozin.secrets 的值会被替换为 ***。不要放个人数据:电脑前的任何人都能看到这一行。
ctx.status('Synced 52 patients', 'info', { done: 52, total: 52 });ctx.log(text) 尚未发布
向 Extension 的日志写一行。dozin.secrets 的值会被替换为 ***。无返回值。
ctx.log('round started');ctx.readJson(rel) 尚未发布
读取 dataDir 内的一个 JSON 文件。
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
rel | string | 是 | 相对于 dataDir 的路径 |
返回 Promise<unknown>:解析后的值;文件不存在时为 undefined。路径为空或在 dataDir 之外时以 PATH_OUTSIDE_DATA reject;文件不是有效 JSON 时以解析错误 reject。
ctx.writeJson(rel, value) 尚未发布
写入 dataDir 内的一个 JSON 文件,一步完成替换,所以崩溃时不会留下写了一半的文件。
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
rel | string | 是 | 相对于 dataDir 的路径 |
value | unknown | 是 | 任何 JSON.stringify 能接受的值 |
返回 Promise<void>。路径为空或在 dataDir 之外时以 PATH_OUTSIDE_DATA reject。
一次运行结束后,它发起的 ctx.site 和 ctx.agent 调用会以 RUN_ENDED reject。
示例
export function activate(api) {
api.registerService({
id: 'sync', name: 'Sync', start: 'auto',
async run(ctx) {
while (!ctx.signal.aborted) {
const state = (await ctx.readJson('state.json')) ?? { runs: 0 };
state.runs += 1;
await ctx.writeJson('state.json', state);
ctx.status(`Run ${state.runs} done`);
await new Promise((resolve) => setTimeout(resolve, 15 * 60 * 1000));
}
}
});
}