Show where a Bloom launch spends its time, and add --no-watch - #8205
Open
JohnThomson wants to merge 2 commits into
Open
Show where a Bloom launch spends its time, and add --no-watch#8205JohnThomson wants to merge 2 commits into
JohnThomson wants to merge 2 commits into
Conversation
Launches here kept failing with "Bloom did not emit BLOOM_AUTOMATION_READY
within 120000 ms", after which the launcher tears the whole stack down. The
message named a symptom and nothing else, so this adds the missing facts.
The launcher now logs phase timings for each launch, measured from the moment
dotnet is spawned -- which is also when the launch timeout starts, so the
phases add up to exactly the budget that timeout is policing. That matters,
because the clock was never really about "Bloom starting": it covers dotnet
watch's own startup, any restore, the MSBuild build, and only then Bloom's
initialization.
On an idle machine here, a launch reports:
dotnet spawned +0.0s
dotnet watch ready +2.4s (2.4s total)
msbuild started +37.4s (39.8s total)
msbuild succeeded +16.3s (56.0s total)
Bloom reported automation-ready +2.0s (58.0s total)
Bloom itself starts in two seconds and the build takes sixteen, but 37 seconds
-- 64% of the launch -- goes between "Hot reload enabled" and the build even
starting, and the only thing dotnet prints in that window is NuGet evaluation
warnings. That is dotnet watch working out its watch file-set by evaluating
the project. On a machine that is short of memory and paging, that is what
pushes a launch past two minutes.
Also adds BLOOM_LAUNCH_TIMEOUT_MS to override the 120s (0 waits forever), which
is what makes it possible to measure a launch without the launcher pulling the
stack down mid-build.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`./go.sh --no-watch` starts Bloom with plain `dotnet run` instead of
`dotnet watch run`. The seam was already there -- watchBloomExe.mjs had a
launchesUnderWatch constant with the not-under-watch branches already written
-- so this just makes it a real option and passes it through from go.mjs.
Measured on this machine, initial launch:
watch (default) 58.0s, 60.5s
--no-watch 48.9s
so about 10s, ~17%. Less than hoped: the 37s that passes under watch before
MSBuild starts is NOT all watch overhead. Plain `dotnet run` prints the same
NuGet evaluation warnings twice (a restore pass and a build pass) and takes
nearly as long to get going, so most of that window is evaluation and restore
that both modes pay for.
Where it shines is the restart: with the build already up to date, a restart in
this mode reaches automation-ready in 2.9s. Combined with not leaving a
dotnet watch and its file watchers resident, that makes it the better mode on a
machine short of memory -- which is what sent us looking, since a paging
machine was pushing launches past the two-minute timeout.
The trade-off is real and the launcher says so on startup: C# changes are not
picked up until you restart, and Bloom's restart toast never appears because
nothing is watching. Both modes were launched and verified after this change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Two small improvements to the dev launcher (
./go.sh→go.mjs→watchBloomExe.mjs), prompted byBloom taking so long to start that the launcher's 120s timeout was firing.
1. Show where a launch spends its time
Startup was slow and we had no idea which part was slow. The launcher now stamps each phase it
goes through (init, restore, build, waiting for Bloom to be ready) and reports how long each took,
so a slow launch tells you what was slow instead of just timing out.
Also, the launch timeout is now settable via
BLOOM_LAUNCH_TIMEOUT_MS, and setting it to0means"no timeout" — useful on a machine that's genuinely slow (or thrashing) where you'd rather wait than
have the launcher give up.
2.
--no-watchdotnet watchcosts real time at startup (setting up file watchers over the whole C# tree) andearns it back only occasionally, since plenty of C# changes need a restart anyway.
./go.sh --no-watchstarts Bloom with a plain
dotnet runinstead. It prints a warning at startup that C# changes willneed a restart, so you can't forget which mode you're in.
Measured on my machine: skipping the watch saves roughly 10s of a ~60s cold start (~17%). Not the
whole story — the bigger costs are elsewhere — but it's free, and the phase timing above is what
will let us go after the rest.
Testing
I have been running Bloom in
--no-watchmode throughout a long session of front-end work(the front-end dev server is unaffected either way), and restarting it for C# changes via the
launcher's restart control. Default behaviour (no flag) is unchanged.
Devin review
This change is