Files
Nexus/docs/design/specs/2026-06-08-script-exec-global-progress-telegram-design.md
2026-07-08 22:31:31 +08:00

6.1 KiB
Raw Permalink Blame History

设计说明 — 脚本库全局执行进度 + Telegram 结果通知

日期: 2026-06-08
基线: main@3f995a7
参考 UI: VSnackbarQueue Promise · VProgressLinear chunks · VAlert 可关闭

背景与目标

运维在脚本库对 300+ 台执行命令时,需要:

  1. 点击执行后立即返回,不阻塞对话框/页面,可在其他页面继续操作。
  2. 全局顶部展示执行进度(流动状进度条 +「已进行 3 台,剩余 363 台」)。
  3. 执行结束时:浏览器提醒 + 短促提示音;可点击关闭,1 秒渐隐
  4. Telegram 推送汇总:成功 N / 失败 M;失败项含服务器名称、退出码、原因摘要(可多条)。

现状差距

能力 现状 缺口
后台执行 POST /api/scripts/exec 同步 await 全部批次(366 台可阻塞数十秒~数分钟) 须改为「创建 execution → 立即返回 → 后台 dispatch」
进度 UI ScriptsPage 底部「批量执行状态」+ 10s 轮询 须全局 Snackbar Queue + 细粒度进度
实时推送 Push 有 /ws/sync;脚本 WS 须新增 script_progress 广播或复用 alerts WS
Telegram 仅有 send_telegram_sync_complete 须新增 send_telegram_script_complete + 设置项
完成提醒 终态仅 snackbar(warning) 须 Alert + 声音 + 渐隐动画

方案对比

A. 后台执行 + WebSocket 进度(推荐)

POST /exec → 202 + execution_id
       ↓
asyncio.create_task(run_batches)
       ↓ 每完成一台/一批
broadcast_script_progress → /ws/alerts 或 /ws/scripts
       ↓ 终态
send_telegram_script_complete + WS terminal event

优点:进度实时、与 Push 模式一致、Snackbar 可流畅更新。
缺点:需改后端执行模型 + WS 协议。

B. 仅前端全局轮询

API 仍同步,或改为后台但前端 2s 轮询 GET /executions/{id}

优点:改动小。
缺点:366 台时 API 仍可能长时间不返回;轮询粗、流量大;不符合「先返回再执行」。

选定 A

接口与数据模型

API 变更

端点 变更
POST /api/scripts/exec 创建 execution + init_live立即返回 { id, status: "running", progress: "0/N" }dispatch 在 asyncio.create_task
POST /api/scripts/executions/{id}/retry 同上异步模式
GET /api/scripts/executions/{id} 不变(轮询兜底)

兼容:长任务(long_task)逻辑保持;短任务也走同一异步路径。

WebSocket 消息(扩展 /ws/alerts 或新建 /ws/scripts

推荐 扩展 /ws/alertsApp 已连接),新增 type

{
  "type": "script_progress",
  "execution_id": 6,
  "label": "磁盘检查",
  "status": "running",
  "done": 3,
  "success": 3,
  "failed": 0,
  "total": 366,
  "remaining": 363
}

终态:

{
  "type": "script_complete",
  "execution_id": 6,
  "status": "partial",
  "success": 363,
  "failed": 3,
  "total": 366,
  "failed_preview": [
    { "server_id": 1, "name": "srv-a", "exit_code": 1, "summary": "Connection timed out" }
  ]
}

done = 已有终态结果的台数(含失败);success 沿用 execution_progress_summary 语义(失败不计入 success)。

Telegram

新增 send_telegram_script_complete(),参照 send_telegram_sync_complete

  • 设置项:NOTIFY_SCRIPT_COMPLETE(默认 trueSettings 可关)
  • 正文:脚本名/命令摘要、操作人、成功/失败/总计、耗时
  • 失败明细:每台一行 — 名称 · exit码 · 原因摘要HTML escape + sanitize
  • 超过 Telegram 4096 字符:首批 20 条 +「…及其他 N 台,详见 Nexus #/scripts 执行 #id」
  • 触发点:script_execution_store.apply_update(..., terminal=True) 或 dedicated on_execution_terminal hook

前端全局 UI

组件 用途
VSnackbarQueue 全局顶部(location="top"),每任务一条 queue item
VProgressLinear buffer-value + indeterminate 交替 「流动状」进度;model-value = done/total*100
VAlert closable + @click:close + CSS transition 1s 完成提醒条(成功/部分失败/全失败配色)
Audio / new Audio('/app/notify.mp3') 终态播放一次(用户可浏览器静音)

Snackbar 文案示例(进行中):

磁盘检查 · 已进行 3 台,剩余 363 台

Promise 模式queue 项在 script_complete 时 resolve,切换为 Alert 或关闭 snackbar 并弹出 Alert。

状态管理:新建 useScriptExecutionQueuePinia 或 composable singleton),ScriptsPage / SchedulesPage 提交后只调用 queue.track(executionId, label, total)移除页面内 trackedExecs 面板(或保留「详情」链接)。

安全与性能

  • WS 消息仅 JWT 已连接管理员可见;不含完整 stderr(Telegram 同样截断)。
  • 后台 task 须捕获异常写 execution failed,避免 silent hang。
  • 366 台 Telegram 分条/截断,防 flood。
  • 单 workercreate_task 绑定 primary worker 约定(与现有 background tasks 一致)。

验收标准

  • 选 366 台点执行 → 1s 内关闭对话框,顶部出现进度 Snackbar。
  • 切换至 Dashboard/其他页,进度条仍更新。
  • 文案显示「已进行 X 台,剩余 Y 台」,X+Y=总数(进行中);Y 随完成递减。
  • 全部结束:短促提示音 + 顶部 Alert「成功 363 台,失败 3 台」;点击后 1s 渐隐
  • Telegram 收到汇总 + 3 台失败名称与原因。
  • Settings 关闭 NOTIFY_SCRIPT_COMPLETE 时不发 Telegram。
  • 长任务 / retry / 临时命令 行为一致。

非目标(本期不做)

  • 多 execution 合并为一条 Telegram(每台 execution 一条)。
  • 浏览器 Push Notification API(仅站内 Alert + 声音)。
  • 修改 success/total 进度语义。