Repository navigation
perf: The caller-note backfill also reads the next caller level's dlls, so the run after a cold run reads none - #3298
Conversation
The backfill reads only the dlls the run's note step refused at the first incomplete caller level, so the next level's dlls are found only by the next run. Pin the intended behavior before implementing it: after reading, the backfill recomputes the refused dlls (a function passed to Start), reads the new ones, skips ones it already tried, stops at the caller-depth round limit, and honors cancels before and inside the recompute. Start takes the recompute function now; the stub ignores it, so the new recompute tests fail while the guard tests (empty list, cancel before the recompute) pass.
…vel needs The note step's caller closure stops at the first level with a refused dll, so the backfill only learned that level's dlls and the next run still read one dll and refused another. After reading, the backfill now calls the run's recompute function, reads the dlls it newly refuses, and repeats until nothing new is refused or the caller-depth limit of rounds is reached. Tried paths are remembered so a dll that fails to read is not retried, the cancel is checked before each recompute so a waiting run is not held up by it, and the complete entry gains rounds while requested now counts the distinct dlls tried.
…notes The run remembers the project root and note requests, and on End passes the backfill a function that, on the main thread under a fresh cache hold, rebuilds the notes with a load budget of zero and returns the dlls it refused. Nothing is read by it and it writes no budget-exhausted entry, since no run's note was omitted. A run that built no notes returns an empty list without hopping threads.
…un reads nothing Add a two-level cross-assembly caller chain (host in the test assembly, relay in the cross-assembly fixture, caller in a new level-2 fixture assembly) and an E2E test: the cold run refuses only the relay's dll, the backfill reads it and then the level-2 dll found by its recompute, writes no extra budget-exhausted entry, and the next run reads no dll. The test reads the patched host through reflection: a direct call from the test assembly is itself a compiled caller, and the closure would stop at it before walking the relay's level.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Summary
The caller-note step of a hot reload run reads at most one uncached compiled dll; the background backfill then reads the dlls the budget refused. But the caller closure stops at the first caller level with a refused dll, so the backfill only learned that level's dlls. The dll one caller level further was found by the next run, which read one dll and refused another (measured: the first warm run after a cold run spent 185–237 ms in caller notes vs. 110–120 ms fully warm).
Now, after reading the refused dlls, the backfill asks the run to recompute its notes with a load budget of zero (on the main thread, under a fresh cache hold, discarding the notes) and reads the dlls that recompute refuses. It repeats until nothing new is refused, capped at
MaxCallerDepth(4) recomputes. After a cold run's backfill finishes, the next run reads no dll.HotReloadCallSiteBackfill.Starttakes the recompute function (findRefusedAgain);RunAllAsyncloops read → recompute.OperationCanceledExceptionfilter.hot_reload_caller_note_load_budget_exhausted(no run's note was omitted).HotReloadCompiledCallersRunremembers the project root and requests and passesFindRefusedAgainAsynconEnd; a run that built no notes returns an empty list without hopping threads.hot_reload_caller_note_backfill_completegainsrounds(recomputes done), andrequestednow means the distinct dlls actually tried (previously the length of the initial list).docs/vibe-logs.mdupdated.The closure's early stop on an incomplete level is unchanged (it is what makes a note safe).
Input space covered (
HotReloadCallSiteBackfillTests)E2E:
Run_WhoseNoteStepRefusedADllWithACallerChain_BackfillsTheNextLevelSoTheNextRunReadsNothinguses a new two-level chain (host in the test assembly → relay in the cross-assembly fixture → caller in a newCallSiteCrossAssemblyLevel2fixture assembly). The host is read through reflection in the test, because a direct call from the test assembly would itself be a compiled caller at which the closure stops.Mutation checks
Each run against the committed head, then reverted:
Start_WhenCancelledBeforeRecompute_DoesNotRecomputeandYieldToRunAsync_WhileADllIsInFlight_...fail...._DoesNotRetryThemand..._ReadsEachNewDllOncefail...._StopsAtTheRoundLimitfails.Verification
Starttaking the new argument but ignoring it, exactly the recompute tests failed (7) and the guard tests passed.HotReloadCallSiteBackfillTests(17),HotReloadCallerNoteBackfillE2ETests(4),HotReloadCompiledCallersTests(3),HotReloadCallSiteBackfillEditorHooksTests(2),HotReloadCallSiteScannerTests(30),HotReloadOneShotCallerClosureTests(2),OnionAssemblyDependencyTests(83).