Repository navigation
Compile: record the phase split in the activity log — stop guessing where 45s goes - #685
Merged
Merged
Conversation
…here 45s goes Three fixes were attempted for the 2026-07-27 outage and all three were guesses at a mechanism, because nothing measures the compile's internals. The activity log showed 45.20s between "Invoking compiler…" and the source queries resolving, against 2.83s of Roslyn, but WHY was reconstructable only by subtracting microsecond timestamps and then inventing a story to fit. Each story was wrong: - "the cached synced query stalls" → the uncached probe never fired (#682) - "a lost Initial waits for the 45s heartbeat" → starting the heartbeat early changed nothing measurable in production (#684: 48s before, 57s after) - "15s GetMeshNode + 30s SnapshotSources = 45s" → Loki shows those 15s stalls happening on LocalSyncDemo/_Sync/party-1, never on the compile path So measure instead. Three clocks, written into the compile's OWN ActivityLog, so one `get @{Type}/_Activity/compile-…` shows the split with no log correlation: ⏱ NodeType definition resolved in {ms}ms (ok | NULL — the read stalled …); source-freshness scan {ms}ms. ⏱ Source discovery took {ms}ms (synced query | caller-supplied override) — everything below this line is Roslyn. The null-definition case is called out explicitly because that read is a bounded 15s EmitNull: on a stall it yields null and the compile proceeds against a null definition, which the code already documents as "a silently wrong compile". Logging only — no behaviour change. 647/647 Graph tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds phase-level timing instrumentation to MeshNodeCompilationService so compile activities record where time is spent (NodeType definition resolution, source freshness scan, and source discovery), making 45s+ stalls diagnosable directly from the per-compile ActivityLog.
Changes:
- Record definition-resolution and source-freshness timings into the compile
ActivityLog. - Record source-discovery timing (synced query vs caller override) into the compile
ActivityLog.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+713
to
+716
| var discoveryLog = AppendInfo(log, | ||
| $"⏱ Source discovery took {discoveryClock.ElapsedMilliseconds}ms " | ||
| + $"({(sourcesOverride is not null ? "caller-supplied override" : "synced query")}) — " | ||
| + "everything below this line is Roslyn."); |
Contributor
Contributor
Contributor
Contributor
Contributor
Contributor
Contributor
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.
Why this exists
Three fixes were attempted for the 2026-07-27 outage tonight. All three were guesses at a mechanism, because nothing measures the compile's internals. The activity log shows 45.20 s between "Invoking compiler…" and the source queries resolving, against 2.83 s of Roslyn — but why was reconstructable only by subtracting microsecond timestamps and then inventing a story to fit.
Every story was wrong:
Initialwaits for the 45 s heartbeat (#684)15 s GetMeshNode + 30 s SnapshotSources = 45 sLocalSyncDemo/_Sync/party-1(82×), never on the compile pathWhat it adds
Three clocks, written into the compile's own
ActivityLog, so a singleget @{Type}/_Activity/compile-…shows the split with no log correlation and no arithmetic:The null-definition case is called out explicitly because that read is a bounded 15 s
EmitNull: on a stall it yieldsnulland the compile proceeds against a null definition — which the surrounding comment already admits is "a silently wrong compile". If that is what's happening on memex, this line says so outright.Scope
Logging only, no behaviour change. 647/647 Graph tests pass.
What to do with it
Deploy, run one compile of
Store/Coupon(the type measured all night — 23 Code nodes across four types viashared=), and read the activity node. The 45 s is in exactly one of three places, and this says which. Then fix that, with evidence instead of a fourth story.🤖 Generated with Claude Code