fix: On Windows, uloop status reports a dialog as soon as it opens
Merged
HA
14h ago+473+473+012345678901234567890123456789-54-54-01234567890123456789
Summary
- On Windows,
uloop status(and the check before every command) reportsBlockedByDialogwithin about a third of a second after a dialog opens, even in Editors older than 6000.7 that cannot report their dialogs. uloop statuswith no dialog open is no slower, because the Editor now tells the CLI its own process ID instead of the CLI searching for it.
User Impact
- Before: an Editor older than 6000.7 was reported
Readyfor about a second after a dialog opened, because uloop looked at Unity's windows only after the main thread had been still for a second and a second answer confirmed it. A command sent in that time went to an Editor that could not run it. - After: on Windows, an answer that would let the reader send a command (
Ready,Compiling,ImportingAssets) gets one look at Unity's windows right away once the main thread has been still for 0.3 seconds. A dialog found makes itBlockedByDialog; no dialog, or a look that fails, keeps the usual report with no extra hint. - A main thread that keeps running gets no look, so a window that only looks like a dialog (a message box with no owner that another thread opened) cannot make status, or the check before every command, refuse commands while the Editor can run them.
uloop statuswhile a dialog is open also returns faster on Windows (about 1.1 s instead of 2.1–2.4 s), because the five-second path no longer searches the process list either.- macOS and Linux keep the look after a short stall.
Changes
- The Editor reads its process ID once when the server starts and reports it as
ProcessIdinget-editor-status. No protocol version change: the field is additive, and an old package simply reports nothing. unitydialog.Inspector.InspectEditortakes that process ID and skips the process search (which starts PowerShell on Windows, about 360 ms).Inspectkeeps its behavior by passing zero.- The project runner passes the reported process ID to every look. On Windows it looks once right after the first answer when the main thread has been still for 0.3 seconds or more, instead of asking the Editor again after a one-second stall. Why 0.3 seconds: the Editor loop is ticked at 6 Hz or more, so a running main thread is never still for much over 0.17 seconds.
- The status skill says when each operating system looks.
- Shared release input stamps are refreshed for the
cli/commonchange.
Known cost
With the new project runner and a package that predates ProcessId, each Windows command whose main thread has paused pays the process search on its pre-send check (status and get-logs both measured at about 410–440 ms instead of 35–75 ms). The project runner is pinned by the package, so this pairing should be rare.
Verification
scripts/check-go-cli.sh(format, vet, lint, tests, build) on macOS;go test ./...,go vet ./...,golangci-lint fmt --diffandgolangci-lint runincli/common,cli/project-runnerandcli/dispatcheron Windows;GOOS=windows go vet ./...on macOS.go test ./internal/architecture/,go run ./cmd/check-release-triggers --base origin/feat/modal-dialog-detection-integration --head HEAD,go run ./cmd/check-skill-size, andgo run ./cmd/sync-tool-docs --checkincli/release-automation.uloop compile, anduloop run-tests --filter-type regex --filter-value "EditorStatusBridgeCommandTests|UnityCliLoopExecutionRouterActivityTests|JsonRpcRequestProcessorTests"(30 passed).- New Go tests run on any OS by replacing the operating system: Windows looks right after the first answer once the main thread has been still for exactly 0.3 seconds or longer (Ready / short stall / Compiling / ImportingAssets) and passes the reported process ID; a main thread still for 0.1 or 0.29 seconds gets no look even when a dialog-like window is there; no dialog keeps Ready with one look and no recheck; a failed look prints the same JSON as before; Busy and an Editor-reported dialog get no look; macOS keeps no look for a running main thread; the inspector skips the process search when given a process ID and searches when not.
- The 0.3-second condition was added after the Windows measurements below, from review. It has not run on a Windows Editor yet; the first run after a dialog opened in those measurements had a main thread still for 0.34 seconds, so it would still be caught.
Measurements on Windows, with no dialog open, 10 runs each (median / max, ms):
| Command | Before (Unity 6000.3) | After (Unity 6000.3) | After (Unity 6000.7) |
|---|---|---|---|
uloop status | 33 / 249 | 35 / 40 | 38 / 42 |
uloop get-logs | 72 / 94 | 76 / 95 | 91 / 108 |
uloop get-dialogs (for reference) | 406 / 424 | 407 / 412 | — |
Get-CimInstance in a new PowerShell (for reference) | 363 / 421 | — | — |
Dialog opened from the Editor loop with no command running, then uloop status every ~0.6 s:
- Unity 6000.3:
Readyuntil the dialog opened, thenBlockedByDialogfrom the first run after it opened (main thread still for 0.34 s at that run); before this change, runs in the first second after a dialog opened wereReady. - Unity 6000.7 (reports its dialogs itself):
BlockedByDialogfrom the first run after the dialog opened, with every run under 0.1 s. - With the dialog open on 6000.3,
uloop statustook 1.08–1.09 s in 5 runs (2.1–2.4 s before), anduloop get-logswas refused withBLOCKED_BY_DIALOG.