fix(gateway): hold the agent lock when deleting a session - #103
Draft
cursor[bot] wants to merge 1 commit into
Draft
cursor[bot] wants to merge 1 commit into
cursor[bot] wants to merge 1 commit into
Conversation
DELETE /api/sessions ran on the HTTP thread while agent_run still held the loaded transcript. session_save then recreated the row, so a dashboard delete during a reply restored the conversation. dispatch_delete_session takes the same mutex /reset already uses. Co-authored-by: esadrianno <esadrianno@gmail.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug and impact
DELETE /api/sessions/:idruns on the gateway thread and calledsession_delete()with no agent mutex.agent_run()loads the transcript, spends the model call with that copy, thensession_save()writes it back withINSERT ... ON CONFLICT DO UPDATE.Trigger: open the dashboard, send a chat message, and delete that session while the reply is still in flight. The delete removes the row, then the in-flight save puts the old transcript back, including whatever the user was trying to remove.
Root cause
/resetalready takesagent_lock()aroundsession_delete()so it cannot raceagent_run(). The dashboard route did not. The HTTP server is a separate thread from the main loop, and the race window is the whole model call.Fix
dispatch_delete_session()takes the same mutex, deletes the row, and releases it.handle_session_deleteuses that helper. The lock is not held across channel I/O.Validation
make test_dispatchand./build/test_dispatch(new case asserts the mutex is held during the delete and that the row is gone).src/gateway/routes.ccompiles with-DSHELLCLAW_GATEWAY -Werror.