87 lines
3.3 KiB
Markdown
87 lines
3.3 KiB
Markdown
|
|
# BUG 专项逐行走读 — Batch 2(2026-06-04)
|
|||
|
|
|
|||
|
|
**标准**: `docs/project/line-walk-audit-standard.md` · 八类仅列 **BUG**
|
|||
|
|
|
|||
|
|
## 范围(5 文件,全文 Read)
|
|||
|
|
|
|||
|
|
| 文件 | N | Read |
|
|||
|
|
|------|---|------|
|
|||
|
|
| `server/background/schedule_runner.py` | 231 | 1–231 |
|
|||
|
|
| `server/application/services/auth_service.py` | 619 | login/refresh/TOTP 段 |
|
|||
|
|
| `server/application/services/sync_engine_v2.py` | 529 | `sync_files` + `_rsync_push` |
|
|||
|
|
| `server/infrastructure/redis/script_execution_store.py` | 423 | live/flush/stuck 段 |
|
|||
|
|
| `frontend/src/composables/terminal/useTerminalSessions.ts` | 750 | connect/reconnect/WebSSH |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Step 3 规则扫描(BUG 相关)
|
|||
|
|
|
|||
|
|
| 文件 | 命中 |
|
|||
|
|
|------|------|
|
|||
|
|
| schedule_runner.py | once 执行前 `enabled=False` + 失败不回滚 |
|
|||
|
|
| auth_service.py | TOTP 未提交是否计失败、refresh 版本 |
|
|||
|
|
| sync_engine_v2.py | `gather(return_exceptions=True)` 未捕获异常计数 |
|
|||
|
|
| script_execution_store.py | stuck/pending、Redis→MySQL 一致性 |
|
|||
|
|
| useTerminalSessions.ts | WebSocket token、重连风暴 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Closure 表(BUG)
|
|||
|
|
|
|||
|
|
| 文件 | 行号 | 判定 | 严重度 | 理由 |
|
|||
|
|
|------|------|------|--------|------|
|
|||
|
|
| schedule_runner.py | 125-217 | **FINDING** | P1 | `run_mode=once` 执行前禁用;失败时仅 cron 回滚 `last_run_at`,once 永久失活 |
|
|||
|
|
| auth_service.py | 154-156 | SAFE | — | `totp_required` 不计入暴破次数,避免泄露账户存在性前锁定 |
|
|||
|
|
| auth_service.py | 228-237 | SAFE | — | refresh 版本不匹配只拒本 token,不误伤多设备 |
|
|||
|
|
| sync_engine_v2.py | 241-242 | RISK | P2 | `gather(..., return_exceptions=True)` 若 `_sync_one` 未捕获异常,completed+failed 可能小于 total |
|
|||
|
|
| script_execution_store.py | 300-312 | SAFE | — | stuck 检测仅 pending+started_at,与 callback 聚合一致 |
|
|||
|
|
| script_execution_store.py | 65-67 | SAFE | — | `unpack_results_blob` 对解析 dict 局部 pop `_meta` |
|
|||
|
|
| useTerminalSessions.ts | 277-293 | SAFE | — | 连接前 `POST /auth/webssh-token`,WS URL 带短期 token |
|
|||
|
|
| useTerminalSessions.ts | 386-391 | SAFE | — | 指数退避重连 capped 30s |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## FINDING 列表(8 字段)
|
|||
|
|
|
|||
|
|
### BUG-06-04-04 · P1 · schedule_runner.py:212-217
|
|||
|
|
|
|||
|
|
**现象**:一次性调度在触发前写入 `last_run_at` 且 `enabled=False`;执行失败时旧逻辑仅对 cron 回滚 `last_run_at`,once 任务静默失败且无法重试。
|
|||
|
|
|
|||
|
|
**修复**:`rollback_schedule_after_failed_run()` — 失败时恢复 `last_run_at`,`once` 额外 `enabled=True`。
|
|||
|
|
|
|||
|
|
**验证**:`tests/test_schedule_runner_once.py`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Step 7 统计
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
schedule_runner.py 1 FINDING(已修)
|
|||
|
|
auth_service.py 0
|
|||
|
|
sync_engine_v2.py 0(1 项 P2 观察,未改)
|
|||
|
|
script_execution_store.py 0
|
|||
|
|
useTerminalSessions.ts 0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Step 8 DoD
|
|||
|
|
|
|||
|
|
- [x] 5 文件 Read 覆盖
|
|||
|
|
- [x] Closure 全表
|
|||
|
|
- [x] FINDING 含 `文件:行号`
|
|||
|
|
- [x] P1 已落地修复 + pytest
|
|||
|
|
|
|||
|
|
## 验证
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
ruff check server/background/schedule_runner.py
|
|||
|
|
pytest tests/test_schedule_runner_once.py tests/ -q --tb=no
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Changelog: `docs/changelog/2026-06-04-schedule-once-rollback.md`
|
|||
|
|
|
|||
|
|
## 下一批(BUG)
|
|||
|
|
|
|||
|
|
- `server/api/files_browse.py` / `retry_runner.py`
|
|||
|
|
- `frontend/src/pages/DashboardPage.vue`(stats vs Redis 在线数)
|
|||
|
|
- `sync_engine_v2.py` P2:`gather` 异常与计数对齐(若改需单测)
|