Repository navigation
macos-host: say which phase the UI root search is in, so slow stops looking hung - #494
Merged
Merged
Conversation
…ooking hung
The Spotlight autopilot app was reported broken on 2026-09-12. It was not: the
root search took 81 seconds on that client and the bot then flew its route
perfectly, eight jumps and counting. What the operator had on screen for those
81 seconds was the bot's own status line, reprinted unchanged every tick:
EVE Online framework status:
Search the address of the UI root in process 87630
That line is the bot's, re-derived each tick from a setup state that has
genuinely not moved, so it says nothing about whether the host is alive. And
this repository has shipped a hang that presents identically -- #455, where
`character_name` on the wrong object turned every client-list request into
ProcessNotFound and the framework rebuilt the volatile process forever. So
"working, just slow" and "wedged" looked the same, and an operator who had
already been burned by the second read this as the second.
Each phase now announces itself on stderr with an elapsed clock, and a
rate-limited heartbeat marks time *inside* a phase -- the phase lines alone
leave a silence as long as the longest phase, which is the gap this is about.
The heartbeat is on the request side because that is what runs once per tick;
the worker is inside a single phase for tens of seconds with no loop to hang a
clock on.
**It corrected a belief in this file on its first run**, which is the argument
for real phases over a spinner. Timed cold:
dumping process memory 10s
indexing the dump ~0s
scanning for a seed object 24s
bootstrapping the str type 20s
walking up to the UI root 41s
total 95s
The dump was labelled "the long one" and is the shortest substantive phase;
`_cached_ui_root` still calls it "(~20-40s) ... the whole cost of starting the
bot" and it is a tenth of the wall clock. The cost is the two repr scans and the
walk to the root, which is not where either comment pointed.
Reporting can never break the search it reports on: the whole reporter is
wrapped, because a search dying for want of describing itself would be this
change causing the failure it exists to explain. The protocol answer is
untouched -- `SearchUIRootAddressInProgress` still keeps the framework waiting.
Verified in tools/macos-host/tests/test_root_search_reports_progress.py (14
cases, no client needed), confirmed by five mutations each failing a named case:
the rate limit removed so it floods, the dump phase unannounced, the cached path
silent, the interval cut to a second, and the phase no longer recorded for the
heartbeat to repeat. Confirmed live on a cold search: every phase reported, the
clock visibly moving, 95s end to end.
Co-Authored-By: Claude Opus 5 <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.
The Spotlight autopilot app was reported broken. It was not — the root search took 81 seconds and the bot then flew its route perfectly, eight jumps and counting.
For those 81 seconds the only thing on screen was the bot's status line, reprinted unchanged every tick:
That line is re-derived each tick from a setup state that has genuinely not moved, so it says nothing about whether the host is alive. And this repo has shipped a hang that presents identically — #455, where the framework rebuilt the volatile process forever. "Working, just slow" and "wedged" looked the same, and an operator already burned by the second reasonably read this as the second.
The change
Each phase announces itself on stderr with an elapsed clock, plus a rate-limited heartbeat that marks time inside a phase — the phase lines alone leave a silence as long as the longest phase, which is the whole gap. The heartbeat lives on the request side because that is what runs once per tick; the worker sits inside one phase for tens of seconds with no loop to hang a clock on.
Live, cold:
It disproved a belief in this file on its first run
Which is the argument for real phases over a spinner:
The dump was labelled "the long one" and is the shortest substantive phase.
_cached_ui_rootstill calls it "(~20-40s) ... the whole cost of starting the bot" — it is a tenth of the wall clock. The cost is the two repr scans and the walk to the root, which is not where either comment pointed. Label corrected and the breakdown recorded.Safety
Reporting can never break the search it reports on — the reporter is wrapped, because a search dying for want of describing itself would be this change causing the failure it exists to explain. The protocol answer is untouched:
SearchUIRootAddressInProgressstill keeps the framework waiting rather than tearing the volatile process down.Verified
14 cases in
test_root_search_reports_progress.py, no client needed. Five mutations, each failing a named case: rate limit removed so it floods; dump phase unannounced; cached path silent; interval cut to a second; phase no longer recorded for the heartbeat to repeat. Plus the live cold search above.