fix(orders): synchronize m.stderr writes from parallel dispatch goroutines#1776
Open
eric-jones wants to merge 1 commit intogastownhall:mainfrom
Open
fix(orders): synchronize m.stderr writes from parallel dispatch goroutines#1776eric-jones wants to merge 1 commit intogastownhall:mainfrom
eric-jones wants to merge 1 commit intogastownhall:mainfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…tines memoryOrderDispatcher.dispatch spawns one dispatchOne goroutine per due order; each may call logDispatchError(m.stderr, ...) on the shared writer when its order errors out. Without synchronization, concurrent log lines race on bytes.Buffer.Write (test fakes) or interleave bytes on os.Stderr (production), and `go test -race` flags every concurrent write. Wrap stderr in a mutex-guarded writer at construction time. Production goes through buildOrderDispatcher; the test helper buildOrderDispatcherFromListExec also constructs memoryOrderDispatcher directly, so it wraps too. lockedStderr preserves nil-input semantics so logDispatchError's nil-guard keeps working. Adds direct unit tests for the lockedWriter (16 goroutines x 100 writes under -race; asserts no torn lines and no lost bytes) and for the nil/non-nil construction paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cb92e8a to
0822061
Compare
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.
Summary
memoryOrderDispatcher.dispatchspawns onedispatchOnegoroutine per due order. Each goroutine may calllogDispatchError(m.stderr, …)if its order errors out — butm.stderris unsynchronized.go test -raceflags concurrent writes onbytes.Buffer.Write(test fakes); production writes toos.Stderrare also undefined per Go docs (atomic per-write(2)for small payloads, unspecified inter-call ordering).Wrap
stderrin a small mutex-guarded writer at construction time so the call sites stay unchanged. Both construction paths get the wrap:buildOrderDispatcher(production)buildOrderDispatcherFromListExec(test helper that constructsmemoryOrderDispatcherdirectly)lockedStderrreturnsnilfornilinput sologDispatchError's existing nil-guard keeps its semantics.Testing
make check— 5 pre-existing failures, all documented EXPECT-FAIL on macOS, none introduced by this PR (verified by stashing the change and re-running the same tests in isolation):TestExecCommandRunnerTimeoutKillsChildProcess— fixed by fix(macos): unblock pre-commit hook on macOS dev machines #1729TestBuiltinDoltDoctorReportsTimedOutVersionProbe— fixed by fix(macos): unblock pre-commit hook on macOS dev machines #1729TestBuiltinDoltDoctorBoundsVersionProbe— fixed by fix(macos): unblock pre-commit hook on macOS dev machines #1729TestCityRuntimeManualReloadPanicAfterReloadKeepsReloadReplyAndClears— fixed by fix(test): cancel dispatched orders before t.TempDir cleanup #1741TestCityRuntimeWatchReloadPanicRestoresDirty— sibling of the above (TempDir cleanup race under parallel load); pre-existing flake undermake check, no fix-PR yetgo test -race -count=3 -run '^TestCityRuntimeManualReloadPanicAfterReloadKeepsReloadReplyAndClears$' ./cmd/gc/— race gone (was flagged by the race detector before this change)go test -race -count=1 -run '^TestLockedWriter|^TestLockedStderr' ./cmd/gc/— greengo test -race -count=1 -run 'OrderDispatch|CityRuntimeShutdown|TestSweep|CityRuntimeManualReload|TestLockedWriter|TestLockedStderr' -skip '^TestOrderDispatchRejectsAmbiguousPackPool$' ./cmd/gc/— greenmake check-docs— no docs changed, skippedmake test-integration— not run; past attempts have hit the 30-min timeout with no saved partial outputNote: separate pre-existing race observed
TestOrderDispatchRejectsAmbiguousPackPooltrips a different race under-race: the test fakememRecorderis read from the test goroutine whiledispatchOneis still writing to it. Different surface (test fake field, notm.stderr), pre-existing on origin/main, out of scope for this PR. Skipped via-skipin the broader race check above.Checklist
Need help on this PR? Tag
@codesmithwith what you need.