36 lines
1.2 KiB
Markdown
36 lines
1.2 KiB
Markdown
# 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
|
||
```
|