fix(server): create the default session atomically (no duplicate "Session #1")#332
Merged
Conversation
…sion #1") GetLastSession auto-created a session when the list was empty but released the lock between the empty-check and the creation (and NewSession computed the "Session #N" name outside the lock). Concurrent requests against an empty session list — e.g. the History page's parallel GETs right after "Reset Sessions" — could each create one, yielding two "Session #1" (the flaky "rename a session" e2e test). Move the append into an unlocked newSessionLocked helper used within a single critical section by both NewSession and GetLastSession. Add a -race regression test hammering GetLastSession on an empty service. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # server/services/mocks_test.go
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.
Problem
The
e2ejob flaked onmain(the merge of #315): the "rename a session" test failed withi.e. two sessions named
Session #1existed at once.Root cause
GetLastSessionauto-creates a default session when the list is empty, but it released the lock between the empty-check and the creation, andNewSessioncomputed theSession #Nname outside the lock:When the UI fires concurrent requests against an empty session list — the History page's parallel
GET /sessions+/history+/mocks(+ autorefresh) right after Reset Sessions — two of them each seelen == 0and each create aSession #1. Intermittent → flaky. ViolatesPRINCIPLES.md§3.7 (concurrency safety).Fix
Move the append into an unlocked
newSessionLockedhelper, called within a single critical section by bothNewSessionandGetLastSession(name + carried-over locked mocks are all derived froms.sessions, so they must be computed under the same lock). No behaviour change otherwise.Test
TestGetLastSessionConcurrentfires 50 concurrentGetLastSessioncalls on an empty service and asserts exactly one session is created. Verified it fails on the old code (created 2 sessions, want 1) and passes on the fix; the whole suite is green under-race.🤖 Generated with Claude Code