2026-09-27·by Sijie Wang#standmeet#architecture#design#events

tasks-panel

后台任务面板

上级:events

状态: 已在 v0.1.76 发布(2026-09-27)—— 设计与落地记录见 StandMeet 仓库的 docs/design/event-bus-outbox-webhooks.md。

队列、周期任务、事件流、投递日志都在 admin 里看得见、点得动。参考 River UI 的信息结构,但不引入它(它是独立服务 + 自己的认证);用 dispatcher ops 实现,后台和 MCP 同时可用。owner 也可以直接问自己的 AI“有没有卡住的任务?”。

面板结构

  • ?job=<id> 直接打开某个任务,webhook 投递日志就链到这里。
  • Webhooks 是集成组下单独的后台页(webhooks),不是这个面板的一个标签。
  • 总览上的告警:events_backlog(未扇出超过 1000 条,或最老的超过 5 分钟)、events_poisoned(有隔离的事件)、jobs_discarded(有 discarded 任务)。见 storage-bounds。

取代了进程内注册表

monitor 面板里原来的周期任务列表由进程内 JobRegistry 驱动,重启即丢。注册表和进程内调度器都已删除。周期任务跑在 River 上,instance.jobs(System 面板)改读 River 的持久记录。

ops(声明一次,投影到 admin 与 MCP)

这些 ops 放在 stats 域(internal/stats/ops/tasks.go、tasks_events.go)。后台经 /api/admin/tasks* 和 /api/admin/events* 访问。

  • 读:tasks.overview、tasks.list、tasks.get、tasks.periodic、events.list、events.get。
  • 动作:tasks.retry、tasks.cancel、tasks.run_periodic、events.requeue。
  • 计划里任务的「丢弃」就是 cancel:River 要永久停掉一个任务只能取消它,再加一个动词做的是同一件事。
  • webhooks.deliveries 是 webhook.deliver 任务的筛选视图。见 webhooks。
  • tasks.get 只给任务状态;属于某个域的结果形状由它自己的 op 返回(jobs.fetch_result,completion-hooks)。

这些 ops 走 Inspector 端口,面板不直接依赖 River(queue-behind-ports)。

权限:只在 owner 平面

这些 ops 只有 owner 读和 owner 动作,不进 API-key 面;任务参数和事件 payload 本来就是 thin 的,面板不显示语料正文(event-model)。

手动重试一条卡住的投递

重试策略与失败分类见 retry-has-one-owner。

验收

e2e tasks-panel 和 tasks-panel-more 走真实 UI,每条断言页面上看得见的内容:

  1. 总览数字与实际一致:造 3 个 retryable、1 个 discarded,总览显示 3 和 1,并显示最老待处理年龄。
  2. 任务列表按状态和 kind 筛选,结果只含所选。kind 筛选列出所有已声明的 kind,没跑过的也列。
  3. 任务详情显示每次尝试的错误和下次重试时间。
  4. 点「立即重试」→ 状态变 completed,且对应副作用真发生。
  5. 点「取消」→ 任务不再执行,副作用没有发生(用哨兵任务证明队列在跑)。
  6. 周期任务列表显示上次 / 下次运行;点「立即运行」后上次运行时间更新。
  7. 重启 backend 后面板仍显示重启前的周期任务运行记录。
  8. 事件流:改一篇笔记 → 出现对应事件,详情里列出它扇出到的订阅方及各自状态。
  9. webhook 投递日志可跳到任务详情;「一键重投」把该端点的 discarded 全部送达。
  10. 告警:积压超阈值时面板显示告警,排空后消失。
  11. 权限:用 API key(非 owner)调 tasks.* 被拒。
  12. 完结 hook:批准申请后行状态从「发送中」变「已发送」;mail mock 先失败时显示「失败」,重试后变「已发送」;jobs.fetch_new 超过等待上限时返回回执,jobs.fetch_result 返回同形状的结果(completion-hooks · async-response-contract)。

实现中顺手修的:切换行之后任务详情还作用在旧任务上;已修。

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →