Repository navigation
[Server] Save the session writes of a handler after it resumed - #598
chr-hertel merged 2 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Failed writes remain undetected in key paths, and timed-out teardown can allow a destroyed session to be recreated.
6 open findings
Handle false session save results as exceptions · New Prevent session deletion after lock acquisition timeout · New Avoid JSON-RPC responses for notifications · New Detect in-place mutations of session object values · New Convert failed session saves into logged exceptions · New Document SessionLockException in the public contract · New
What changed in this PR
Adds opt-in per-session locking and preserves session changes made by resumed handlers.
Changes:
- Adds file-based and Symfony-backed session locks.
- Serializes session access and merges resumed-handler changes.
- Adds documentation and extensive concurrency tests.
| File | Description |
|---|---|
CHANGELOG.md |
Records locking and resumed-session behavior. |
composer.json |
Adds optional Symfony Lock support. |
docs/run/sessions.md |
Documents concurrent session handling. |
docs/run/server-builder.md |
Documents the builder lock option. |
src/Exception/SessionLockException.php |
Defines lock failures. |
src/Server/Builder.php |
Configures session locks. |
src/Server/ClientGateway.php |
Propagates notification queue failures. |
src/Server/Protocol.php |
Implements locking and resumed-session merging. |
src/Server/Session/FileSessionLock.php |
Implements filesystem locks. |
src/Server/Session/FileSessionStore.php |
Collects expired lock files. |
src/Server/Session/SessionLockInterface.php |
Defines the locking contract. |
src/Server/Session/SymfonyLockSessionLock.php |
Implements distributed locks. |
src/Server/Transport/BaseTransport.php |
Resumes fibers after yield failures. |
tests/Unit/Server/BuilderTest.php |
Tests builder integration. |
tests/Unit/Server/ClientGatewayTest.php |
Tests notification failures. |
tests/Unit/Server/ProtocolTest.php |
Tests resumed-session persistence. |
tests/Unit/Server/ProtocolSessionLockTest.php |
Tests protocol locking behavior. |
tests/Unit/Server/Session/FileSessionLockTest.php |
Tests filesystem locking. |
tests/Unit/Server/Session/FileSessionStoreTest.php |
Tests lock-file collection. |
tests/Unit/Server/Session/SymfonyLockSessionLockTest.php |
Tests distributed locking. |
tests/Unit/Server/Session/Fixture/HeldElsewhereSessionLock.php |
Simulates lock contention. |
tests/Unit/Server/Session/Fixture/RecordingSessionLock.php |
Records lock operations. |
tests/Unit/Server/Session/Fixture/RecordingSessionStore.php |
Records store operations. |
tests/Unit/Server/Transport/StreamableHttpTransportTest.php |
Tests HTTP concurrency flows. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if ($takesLock && !$this->acquireSessionLock($sessionId)) { | ||
| $this->sendResponse($transport, Error::forServerError(self::SESSION_BUSY_MESSAGE, self::findResponseId($input)), null, ['status_code' => 503]); |
79326f1 to
80dc6c2
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Nested updates can overwrite newer session data, and lock-backend failures can prevent completed responses from being sent.
7 open findings
Handle session lock failures before resuming the response · New Preserve concurrent nested session updates during persistence · New Prevent session deletion after lock acquisition timeout Handle false session save results as exceptions Convert failed session saves into logged exceptions Detect in-place mutations of session object values Avoid JSON-RPC responses for notifications
1 resolved since last review
🧠 Review effort: Balanced
There was a problem hiding this comment.
🟢 Approval recommended
The focused persistence change has regression coverage for session merging and lock handling, with no unresolved findings.
1 open finding
6 resolved since last review
Preserve concurrent nested session updates during persistence Handle session lock failures before resuming the response Prevent session deletion after lock acquisition timeout Handle false session save results as exceptions Convert failed session saves into logged exceptions Detect in-place mutations of session object values
🧠 Review effort: Balanced



Stacked on #584 - only the last commit belongs here; rebased once #584 is.
A handler that writes to its session after it resumed from an elicitation, sampling request or notification loses those writes: nothing saves the fiber's session once it terminates.
Protocolwrites the keys the handler changed since it suspended onto the stored session, under the session lockFixes chr-hertel#85
🤖 Generated with Claude Code