Serialize per-target compiles (CompileScheduler + zinc per-scope lock)#92
Merged
Conversation
Rapid edit-save-edit-save used to fork one compile fiber per didSave, all
racing into the same per-scope zinc analysis store and output jar
(`${scopeId}-analysis` / `${scopeId}-classes`), corrupting each other.
- CompileScheduler: a per-key conflating scheduler. Each target has a
circularBuffer(1) mailbox drained by one worker fiber, so a burst of saves
collapses to "the in-flight compile + at most one newest pending"; the
buffer's evict-oldest policy is what makes the latest save win (dropping(1)
would keep the oldest and discard newer saves). handleDidSave schedules
through it instead of supervising a fresh fiber per save.
- ZincCliServer: a per-scopeId Mutex serializes same-target compiles as a
safety net (distinct targets stay parallel). ZincCliServer.create wires the
lock map.
- DidSaveCompileConcurrencySpec: regression guard asserting peak compile
concurrency stays 1 for the same target. TestServer gains an optional
cspServer injection so the spec can supply a concurrency probe.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f57f97c to
12fe9e8
Compare
This was referenced Jun 15, 2026
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.
What
Concurrent
didSavecompiles of the same build target used to race into the same per-scope zinc analysis store and output jar (${scopeId}-analysis/${scopeId}-classes), corrupting each other. This serializes them at two layers:CompileScheduler(new) — a per-key conflating scheduler. At most one compile per target runs at a time; while one is in flight, further saves coalesce into a single pending re-run that keeps only the newest (intermediate saves dropped).ServerImpl.handleDidSavenow schedules through it instead of supervising a fresh fiber per save.ZincCliServerper-scopeMutex— serializes same-target compiles as a safety net (distinct targets stay parallel).ZincCliServer.createwires the lock map.Test
DidSaveCompileConcurrencySpec(new) — regression guard: a CSP probe records peak concurrency; rapid successive saves of one target must keep it at 1.TestServer.resourcegains an optionalcspServerinjection so the spec can supply the probe (callers inTestClientSpecupdated for the new signature).Notes
./mill __.compileclean and./mill sls.testgreen (598/598).🤖 Generated with Claude Code