Skip to content

feat(session-mgmt): Redis-backed concurrency control for gateway turns#4

Merged
henryqingmo merged 12 commits into
mainfrom
feat/session-mgmt
May 15, 2026
Merged

feat(session-mgmt): Redis-backed concurrency control for gateway turns#4
henryqingmo merged 12 commits into
mainfrom
feat/session-mgmt

Conversation

@henryqingmo
Copy link
Copy Markdown
Contributor

Summary

  • Adds a Redis-backed concurrency layer in front of pipeline.Run() so that different sessions never block each other, only one turn is active per session at a time, and within a turn read-class calls run in parallel while write-class calls are serialized and wait for in-flight reads to drain.
  • Introduces SessionLocker (reference-counted session mutex), TurnRWLock (per-turn reader-writer lock), OperationClassifier (configurable map + read_/get_/list_ heuristic), and ConcurrencyGuard (server-level wrapper with deferred lock release) — all built on go-redis/v9 via inline Lua scripts.
  • Wires the guard into cmd/gateway/server.go handleMCPPost, extends Config with SessionLockTTL (default 60s) and LockAcquireTimeout (default 5s), adds CodeSessionBusy = -32002 JSON-RPC error, extends AgentPolicy with OperationClasses, and adds the redis:7-alpine service to docker-compose.

Spec

Implements .kiro/specs/session-mgmt (Reqs 1.1, 2.1–2.6, 3.1–3.4, 4.1–4.2, 5.1). Validation report: GO. All 14 tasks complete.

Test plan

  • go build ./... and go vet ./... clean
  • TOOLGATE_TEST_REDIS_DSN=redis://127.0.0.1:16380/0 go test -race -timeout 180s ./... — all packages green, race-clean
  • bash scripts/demo_session_mgmt.sh — Redis lock observed during request, cleared after completion, post-restart fresh session acquires its lock immediately (Req 2.4)
  • Manual review of lock acquire/release ordering in cmd/gateway/concurrency_guard.go (acquire SessionLocker → RWLock; defer-LIFO release RWLock → SessionLocker)
  • Manual review of Lua scripts in session_locker.go and turn_rwlock.go for atomicity and TTL refresh semantics

🤖 Generated with Claude Code

henryqingmo and others added 12 commits May 15, 2026 09:19
Add the ConcurrencyGuard integration tests (task 4.4) and the
docker-compose-based end-to-end script (task 4.5). Wire SESSION_LOCK_TTL
and LOCK_ACQUIRE_TIMEOUT into the gateway service and add a hold_ms
argument to the fake upstream so the e2e script can hold a turn long
enough to observe the Redis lock and the SIGKILL restart path.

Also tighten the spec: mark 4.4/4.5 complete, correct the restart
scenario wording to match Req 2.4 (sessions are not preserved across
restarts), and fix mermaid escaping in the design sequence diagram.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@henryqingmo henryqingmo merged commit 618b5f6 into main May 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant