shell: serve forwarded launches as soon as they can be served - #631
Open
deblasis wants to merge 1 commit into
Open
shell: serve forwarded launches as soon as they can be served#631deblasis wants to merge 1 commit into
deblasis wants to merge 1 commit into
Conversation
deblasis
force-pushed
the
single-instance-serve-earlier
branch
from
August 14, 2026 07:10
5baa2b2 to
4aba95a
Compare
A secondary reaches its forward near the top of OnLaunched and gives the primary 2s to answer. The primary did not start listening until the very end of the same method, so most of that budget was spent waiting through session restore, MainWindow construction and Activate, the quake window's HWND, and the hooks -- the same region the launch splash exists to cover. Measured with `just splash-race -DelayMs 0`, six iterations, Debug: the secondary took a mean 4516ms to forward and exit, against 2985ms with the server started earlier. The primary's tail was consuming about 1.5s of the 2s, leaving roughly half a second of margin for a session restore with several windows, a cold cache, or a slower disk to eat. Start the server as soon as a forwarded launch can actually be serviced, which is immediately after the bootstrap host exists. It cannot go earlier. OpenWindowFromLaunch drops a request outright if _configService, _loggerFactory, _lifetimeSupervisor or _bootstrapHost is still null, and the last of those is the line above the new call site. Listening before that would turn a visible failure -- the secondary cannot connect, so it opens its own window -- into a silent one, where it connects, exits, and its launch is discarded. It does not need to go earlier either: everything expensive is below. That drop now logs. It is unreachable as things stand, but it is the one failure that costs a user their launch with no window and no message. Does not close # 629 on its own: the acknowledgement problem noted there is untouched. A secondary still treats a successful pipe write as success, so a primary that dies before opening the window loses that launch.
deblasis
force-pushed
the
single-instance-serve-earlier
branch
from
August 14, 2026 09:34
4aba95a to
c3b410b
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.
Addresses the main finding in # 629.
A secondary reaches its forward at
App.xaml.cs:520and gives the primary 2s to answer. The primary did not start listening until:793, the very end of the same method, so most of that budget was spent waiting through session restore,MainWindowconstruction andActivate, the quake window's HWND, and the hooks -- the same region the launch splash exists to cover.This starts the server as soon as a forwarded launch can actually be serviced: immediately after the bootstrap host exists.
Why that exact line
It cannot go earlier.
OpenWindowFromLaunchdrops a request outright if_configService,_loggerFactory,_lifetimeSupervisoror_bootstrapHostis still null, and the last of those is the line above the new call site. Listening before that would turn a visible failure (the secondary cannot connect, so it opens its own window) into a silent one (it connects, exits, and its launch is discarded with no window and no message).It does not need to go earlier. Everything expensive is below. The callback is
_uiDispatcher?.TryEnqueue(...)and_uiDispatcheris set at:633, so an inbound forward is queued to a UI thread still insideOnLaunchedand runs once it returns -- no deferral queue needed.That silent drop now logs at Error. It is unreachable as things stand, but it is the one failure that costs a user their launch with nothing to show for it.
Measured
just splash-race -DelayMs 0, six iterations each, same machine, Debug build.SecondaryExitMsis how long the secondary took to forward and exit.About 1.5s of the 2s budget reclaimed. The variance collapse is the more telling half: the secondary's exit no longer depends on the primary's progress at all.
What this does not claim
It does not fix a failure that reproduces on HEAD. On current
windowson this machine, forwarding already succeeds 10/10 at 300ms spacing and 6/6 at 0ms. I saw outright failures while developing # 626, but on a tree predating # 627 and # 628 and with a colder cache, and I could not reproduce them here. So this lands as margin and latency, not as a fix for a live defect: it takes the remaining headroom from roughly half a second to essentially the whole budget, which is what a session restore with several windows, a cold cache or a slower disk would otherwise eat.It does not close # 629. The acknowledgement problem noted there is untouched, and this change slightly widens it: a secondary treats a successful pipe write as success, so if the primary now dies between the new call site and the end of
OnLaunched, that launch is lost where previously the secondary would have failed to connect and opened its own window. Fixing that means the secondary waiting for confirmation the window opened, which is a larger change.Verification
Ghostty.Tests1884 passed / 0 failed,Ghostty.Tests.Windows28 passed / 0 failedjust splash-race10/10 at 300ms and 6/6 at 0ms, no secondary splash, every iteration scored