1.6 KiB
1.6 KiB
文件编辑锁契约 v1
公共接口
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}
三个接口均要求用户身份和 Workspace 身份。当前开发基线使用
X-User-ID、X-Workspace-ID,后续接入 JWT 时保持路径和业务 DTO 不变。
加锁成功返回一次性原始 lock_token。心跳和释放请求体均为:
{"lock_token": "raw-token-returned-by-acquire"}
原始 token 只由客户端持有,禁止写入 MySQL 和日志。
Redis 数据
Key: lock:file:{workspace_id}:{storage_object_id}
TTL: 45000 ms
Value:
{
"edit_session_id": "01J...",
"user_id": "01J...",
"display_name": "张三",
"token_hash": "sha256-hex",
"acquired_at": "UTC timestamp"
}
加锁必须使用:
SET key value NX PX 45000
心跳和释放必须执行 Lua 原子操作,并同时比较
edit_session_id + token_hash:
heartbeat: compare owner -> PEXPIRE 45000
release: compare owner -> DEL
禁止使用 GET 后单独 DEL,也禁止在 MySQL 文件表增加 is_locked。
状态与错误
- Redis 是实时锁唯一权威。
edit_sessions记录active/closed/expired,仅用于审计。- 冲突返回 HTTP 409、错误码
FILE_LOCK_CONFLICT,并包含当前编辑者及租约到期时间。 - 错误 token 返回 HTTP 403,且不得续期或释放现有锁。
- 浏览器建议每 15 秒心跳;关闭、断线或心跳超时后由主动释放或 TTL 释放。