docs(architecture): explain gateway session mapping and per-session queueing
This commit is contained in:
+1
-1
@@ -6,6 +6,7 @@ This documentation is written to be useful to both humans and AI agents. If you
|
||||
|
||||
1. Architecture overview (agent-oriented)
|
||||
- `docs/architecture/AGENT_DIAGRAM.md`
|
||||
- `docs/architecture/GATEWAY_SESSIONS_AND_QUEUE.md`
|
||||
- `docs/architecture/TYPESCRIPT_MAP.md`
|
||||
- `docs/architecture/SYMBOL_INDEX.md`
|
||||
- `docs/architecture/CONTRIBUTOR_MAP.md`
|
||||
@@ -37,4 +38,3 @@ flowchart TD
|
||||
NA --> TP[ToolPolicy + ToolRegistry]
|
||||
TP --> TE[ToolExecutor\nhooks + enforcement + audit]
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# Gateway Sessions and Queueing (Agent Execution Model)
|
||||
|
||||
This document explains how the gateway maps WebSocket clients onto durable sessions, and how work is serialised per session so agent execution stays coherent under concurrent requests.
|
||||
|
||||
If you only want the protocol surface, see `docs/api/PROTOCOL.md`.
|
||||
|
||||
## Key Ideas
|
||||
|
||||
- A WebSocket client gets a `connectionId`.
|
||||
- Each connection is attached to a `sessionId`.
|
||||
- Agent work is queued per `sessionId` (FIFO), not per connection.
|
||||
- Sessions persist in SQLite via `SessionManager` even if clients disconnect.
|
||||
|
||||
## Component Map
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph GW[Gateway Process]
|
||||
WS[WebSocket connection\n(connectionId)]
|
||||
GS[GatewayServer]
|
||||
LQ[LaneQueue\nper-session FIFO]
|
||||
SB[SessionBridge\nconnectionId -> sessionId -> AgentOrchestrator]
|
||||
end
|
||||
|
||||
subgraph CORE[Flynn Core]
|
||||
SM[SessionManager\nin-memory cache + SQLite]
|
||||
SS[SessionStore\nSQLite tables]
|
||||
AO[AgentOrchestrator]
|
||||
end
|
||||
|
||||
WS --> GS
|
||||
GS --> LQ
|
||||
GS --> SB
|
||||
|
||||
SB --> AO
|
||||
SB --> SM
|
||||
SM --> SS
|
||||
```
|
||||
|
||||
## Session IDs (What Actually Gets Stored)
|
||||
|
||||
The durable session ID stored by `SessionManager` is:
|
||||
|
||||
`<frontend>:<userId>`
|
||||
|
||||
For the gateway:
|
||||
|
||||
- `SessionBridge.connect()` assigns a `connectionId` (UUID).
|
||||
- It defaults the connection's `sessionId` to `ws:<connectionId>`.
|
||||
- It then calls `SessionManager.getSession('ws', sessionId)`.
|
||||
|
||||
That means gateway sessions are stored as:
|
||||
|
||||
- `ws:ws:<connectionId>`
|
||||
|
||||
This is expected: the gateway adds its own namespace, and the session manager namespaces again by frontend.
|
||||
|
||||
Key files:
|
||||
|
||||
- `src/gateway/session-bridge.ts`
|
||||
- `src/session/manager.ts`
|
||||
|
||||
## Per-Session FIFO Queueing (LaneQueue)
|
||||
|
||||
`agent.send` uses a lane ID derived from the session:
|
||||
|
||||
- lane = `SessionBridge.getSessionId(connectionId)` (preferred)
|
||||
- fallback lane = `connectionId` (only if session lookup fails)
|
||||
|
||||
Within a lane:
|
||||
|
||||
- Only one request executes at a time.
|
||||
- Later requests queue (FIFO) and start after the active request finishes.
|
||||
|
||||
Across lanes:
|
||||
|
||||
- Independent sessions run in parallel.
|
||||
|
||||
Key files:
|
||||
|
||||
- `src/gateway/lane-queue.ts`
|
||||
- `src/gateway/handlers/agent.ts`
|
||||
|
||||
## Cancellation Semantics
|
||||
|
||||
`agent.cancel` performs two separate actions:
|
||||
|
||||
1. Cancels any queued (not-yet-started) work in the lane (`LaneQueue.cancel(laneId)`).
|
||||
2. Requests cancellation of the active agent operation (`AgentOrchestrator.cancel()` via `SessionBridge.cancel()`).
|
||||
|
||||
Important:
|
||||
|
||||
- Cancellation is best-effort for the currently running work: it stops at the next safe point in the agent loop.
|
||||
- Queued work is deterministically rejected.
|
||||
|
||||
Key files:
|
||||
|
||||
- `src/gateway/handlers/agent.ts`
|
||||
- `src/backends/native/orchestrator.ts`
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
"date": "2026-02-15",
|
||||
"summary": "Docs gap pass: added docs/README.md as a start-here index and expanded docs/api/PROTOCOL.md with a precise Mermaid diagram explaining per-session lane queueing and cancellation semantics for agent.send/agent.cancel."
|
||||
},
|
||||
"docs-gateway-sessions-and-queue": {
|
||||
"status": "completed",
|
||||
"date": "2026-02-15",
|
||||
"summary": "Added docs/architecture/GATEWAY_SESSIONS_AND_QUEUE.md to document how gateway connectionIds map to durable sessionIds, how per-session FIFO lane queueing works, and how agent.cancel behaves."
|
||||
},
|
||||
"openclaw-gap-roadmap": {
|
||||
"file": "2026-02-15-openclaw-gap-roadmap.md",
|
||||
"status": "planned",
|
||||
|
||||
Reference in New Issue
Block a user