Files
Nexus/docs/changelog/2026-06-12-watch-ttl-expiry-race-fix.md
T

36 lines
1.2 KiB
Markdown
Raw Normal View History

# Changelog — 监测槽 TTL 到期竞态修复
**日期**2026-06-12
## 摘要
修复 TTL 到期与后台 `expire_due_pins`(5s 探针循环)之间的竞态窗口:槽位短暂显示为空、无法添加/移除、可能触发唯一约束冲突。
## 动机
`list_active_pins_for_admin``monitoring_enabled=true``expires_at<=now` 时排除 pin,但 DB 行仍在且 `monitoring_enabled` 仍为 true,直到探针循环执行 `expire_due_pins`。此窗口内 UI 显示空槽,但 `create_pin` 会因 `uq_watch_pins_admin_slot` 失败。
## 变更
- `WatchService._finalize_due_pins()`:在读/写路径同步到期 pin(暂停 + end session + 按需清 Redis
-`list_slots``pin_server``replace_slot``remove_slot``set_slot_monitoring``set_slot_ttl` 入口调用
- 新增单测:`test_watch_pin_ttl_expiry_list_syncs_before_display``test_watch_pin_ttl_expiry_pin_server_no_duplicate`
- **P2**`WatchSlotRow.onRemove` 失败时 snackbar 提示
## 涉及文件
- `server/application/services/watch_service.py`
- `frontend/src/components/watch/WatchSlotRow.vue`
- `tests/test_watch_pins.py`
## 迁移 / 重启
- 无需迁移
- 需重启 API
## 验证
```bash
.venv/bin/pytest tests/test_watch_pins.py -q
```