docs(locks): document cross-lane named locks (D)

This commit is contained in:
2026-08-04 11:41:54 +07:00
parent c068f0cac6
commit 6c7554dbdc
5 changed files with 135 additions and 3 deletions
+88
View File
@@ -399,6 +399,94 @@ with no slot returns `{"available": false}`.
### Sessions
### Locks
#### List locks
```http
GET /api/locks
```
Returns all currently-held named locks:
```json
{
"locks": [
{
"name": "build",
"holder": "lane3",
"acquiredAt": 1722702012345,
"acquiredMs": 1722702012345
}
]
}
```
Each lock has a `name`, the current `holder` (defaults to `lane<slot>`), and `acquiredAt` / `acquiredMs` (the millisecond timestamp when acquired). If no locks are held, the array is empty.
#### Acquire a lock
```http
POST /api/locks/:name/acquire
```
Request body:
```json
{
"holder": "lane3",
"timeoutMs": 30000
}
```
`holder` defaults to the calling lane (`lane<slot>`) if omitted. `timeoutMs` is optional; without it, the request waits indefinitely. Returns **200** with the acquired lock object:
```json
{
"name": "build",
"holder": "lane3",
"acquiredAt": 1722702012345
}
```
or **408** if the timeout elapses before the lock becomes free:
```json
{
"error": "ETIMEOUT",
"waited": 30000,
"currentHolder": "lane1",
"message": "Lock held by lane1, timeout elapsed"
}
```
#### Release a lock
```http
POST /api/locks/:name/release
```
Request body:
```json
{
"holder": "lane3"
}
```
`holder` defaults to `lane<slot>` if omitted. Returns **200** with the released lock object, or **409** if the holder does not match:
```json
{
"error": "ENOTHOLDER",
"name": "build",
"expectedHolder": "lane3",
"actualHolder": "lane1",
"message": "Lock is held by lane1, not lane3"
}
```
#### List Sessions
```http