重构模型平台前后端并移除Redis依赖
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# 文件编辑锁契约 v1
|
||||
|
||||
## 公共接口
|
||||
|
||||
```text
|
||||
POST /api/v1/files/{storage_object_id}/lock
|
||||
POST /api/v1/file-locks/{edit_session_id}/heartbeat
|
||||
DELETE /api/v1/file-locks/{edit_session_id}
|
||||
```
|
||||
|
||||
三个接口均要求 `X-User-ID` 和 `X-Workspace-ID`。加锁成功返回一次性原始
|
||||
`lock_token`;心跳和释放请求体均为:
|
||||
|
||||
```json
|
||||
{"lock_token": "raw-token-returned-by-acquire"}
|
||||
```
|
||||
|
||||
原始 token 只由客户端持有,数据库只保存 SHA-256 摘要。
|
||||
|
||||
## MySQL 租约
|
||||
|
||||
`edit_sessions` 是实时锁权威:
|
||||
|
||||
- `session_status=active` 且 `expires_at > now()` 表示锁有效;
|
||||
- 同一 `storage_object_id` 同时只能存在一个有效编辑会话;
|
||||
- 心跳更新 `last_heartbeat_at` 与 `expires_at`;
|
||||
- 主动释放将状态改为 `closed`;
|
||||
- 后台清理将超时租约改为 `expired`。
|
||||
|
||||
加锁、心跳和释放都在数据库事务中校验 `edit_session_id + lock_token_hash`。
|
||||
部署时 Runtime 保持单副本;若扩展到多副本,应为加锁查询增加数据库行锁或唯一
|
||||
租约表约束。
|
||||
|
||||
## 状态与错误
|
||||
|
||||
- 冲突返回 HTTP 409、错误码 `FILE_LOCK_CONFLICT`,并包含当前编辑者和租约到期时间;
|
||||
- 错误 token 返回 HTTP 403,且不得续期或释放现有锁;
|
||||
- 浏览器建议每 15 秒心跳,默认租约为 45 秒。
|
||||
Reference in New Issue
Block a user