Skip to content

fix: Wait for V2 server readiness in uloop launch - #2024

Merged
hatayama merged 3 commits into
v3-betafrom
fix/v2-launch-server-readiness
Jul 27, 2026
Merged

fix: Wait for V2 server readiness in uloop launch#2024
hatayama merged 3 commits into
v3-betafrom
fix/v2-launch-server-readiness

Conversation

@hatayama

@hatayama hatayama commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • uloop launch against V2 projects no longer returns early after only seeing a fresh UnityLockfile (or immediately for an already-running Editor). It now waits until the V2 TCP server is actually reachable.
  • Readiness uses UserSettings/UnityMcpSettings.json serverSessionId generation compare (not mtime), TCP connect to the advertised customPort, and absence of Temp/compiling.lock / Temp/domainreload.lock.
  • After the lockfile gate on fresh launch / -r, launch focuses the Editor once so V2's delayCall-based server start can tick. V2 has no equivalent of V3's EditorApplicationTickBridge.SignalTick; without focus, a backgrounded idle Editor can sit forever with an empty serverSessionId.
  • Response messages now report that the V2 uloop server is ready (ServerReady: true, ProjectIpcReady: false) instead of "V2 server readiness was not checked".

Why sessionId, not mtime

Settings mtime is rewritten by many unrelated paths. Domain reload start can write isServerRunning: true with the old serverSessionId, so mtime freshness falsely looks ready. A new serverSessionId is written only when listen succeeds.

Timeout

Probe timeout reuses V3 launch's 10 minutes (launchReadinessTimeout), not the V2 CLI's 3-minute launch readiness window, so V2 and V3 launch wait budgets stay aligned.

Test plan

  • scripts/check-go-cli.sh (format / vet / lint / test / rebuild)
  • Unit tests for settings read (including BOM / .tmp fallback / ignore .bak), session generation, lock busy, port change, and timeout classification
  • Launch flow tests with mocked waitForV2ServerReady (fresh / existing / -r session capture / timeout / focus-before-probe including focus failure)
  • E2E on V2 project UnityPipelineTest with dist/darwin-arm64/uloop:
    • Fresh launch → Ready/ServerReady true, ProjectIpcReady false, message contains V2 uloop server is ready
    • compile succeeds after readiness (first attempt hit a V2 CLI tools-cache sync race; immediate retry succeeded with Success: true)
    • Existing launch → AlreadyRunning: true
    • launch -rRestarted: true
    • launch -qQuit: true
  • Before the focus fix, the same fresh-launch path timed out at 10 minutes with UNITY_STARTUP_TIMEOUT while Unity was alive but isServerRunning: false / empty serverSessionId / no port listener — confirming the timeout path and the backgrounded-Editor diagnosis
  • V3 regression: uloop launch -r on this checkout → Success/Ready/ProjectIpcReady true

Review in cubic

Replace PR #1826's lockfile-only wait and "readiness was not checked"
response with real readiness: UserSettings/UnityMcpSettings.json
serverSessionId generation compare, TCP connect, and compile/reload
lock absence. After the lockfile gate, focus the Editor once so V2's
delayCall-based server start can tick (V2 has no SignalTick workaround).

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@hatayama, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7603af09-f905-4c14-83e4-dc6c53a96184

📥 Commits

Reviewing files that changed from the base of the PR and between d386b27 and 81f45e4.

📒 Files selected for processing (4)
  • cli/dispatcher/internal/dispatcher/launch_focus_log.go
  • cli/dispatcher/internal/dispatcher/launch_v2_lockfile.go
  • cli/dispatcher/internal/dispatcher/launch_v2_server_ready.go
  • cli/dispatcher/internal/dispatcher/launch_v2_server_ready_test.go
📝 Walkthrough

Walkthrough

V2 launch handling captures prior server sessions, polls persisted settings and TCP readiness, waits for Unity to become idle, and reports structured readiness results for fresh, existing, and restarted launches.

Changes

V2 launch readiness

Layer / File(s) Summary
V2 readiness polling and validation
cli/dispatcher/internal/dispatcher/launch_v2_server_ready.go, cli/dispatcher/internal/dispatcher/launch_v2_server_ready_test.go
Reads V2 settings with fallback and BOM support, checks server/session/TCP/lockfile conditions, polls until ready or timeout, and tests readiness edge cases.
Launch flow integration
cli/dispatcher/internal/dispatcher/launch.go, cli/dispatcher/internal/dispatcher/launch_deps.go, cli/dispatcher/internal/dispatcher/launch_v2_lockfile.go
Injects readiness polling, captures previous session IDs, and waits for V2 readiness after lockfile detection or existing-process handling.
Responses and launch scenarios
cli/dispatcher/internal/dispatcher/launch_ready.go, cli/dispatcher/internal/dispatcher/launch_test.go
Reports V2 server readiness with updated flags and messages, covering fresh launches, focus ordering, existing instances, restarts, and timeout errors.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Dispatcher
  participant V2Settings
  participant V2Server
  CLI->>Dispatcher: launch V2 project
  Dispatcher->>V2Settings: read previous session ID
  Dispatcher->>V2Server: poll settings and TCP port
  V2Server-->>Dispatcher: server ready or timeout
  Dispatcher-->>CLI: structured launch-ready response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: V2 uloop launch now waits for server readiness.
Description check ✅ Passed The description matches the changeset and explains the V2 readiness behavior and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/v2-launch-server-readiness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cli/dispatcher/internal/dispatcher/launch_v2_lockfile.go`:
- Around line 89-105: Use a shorter, dedicated timeout for the
waitForFreshUnityLockfile call in the V2 launch flow, matching the intended
approximately 5-second lockfile detection window instead of
launchReadinessTimeout. Keep launchReadinessTimeout for waitForV2ServerReady so
the full readiness wait begins only after the fresh lockfile is detected.

In `@cli/dispatcher/internal/dispatcher/launch_v2_server_ready.go`:
- Around line 193-204: Update waitForExistingV2LaunchReadiness to call
spinner.Stop() immediately when waitForV2ServerReady returns an error, before
invoking clierrors.WriteClassifiedError. Keep the deferred cleanup and
successful response flow unchanged.
- Around line 35-62: Update v2ServerReadyTimeoutError to store the timeout used
by waitForV2ServerReady, and populate that field when constructing the error. In
ToCLIError, derive Details["TimeoutSeconds"] from the stored timeout instead of
the global launchReadinessTimeout, while preserving the existing project-root
and error metadata.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ebd93ef-d956-40cb-9955-2a40c45fdb40

📥 Commits

Reviewing files that changed from the base of the PR and between fcad6e7 and 73dfa40.

📒 Files selected for processing (7)
  • cli/dispatcher/internal/dispatcher/launch.go
  • cli/dispatcher/internal/dispatcher/launch_deps.go
  • cli/dispatcher/internal/dispatcher/launch_ready.go
  • cli/dispatcher/internal/dispatcher/launch_test.go
  • cli/dispatcher/internal/dispatcher/launch_v2_lockfile.go
  • cli/dispatcher/internal/dispatcher/launch_v2_server_ready.go
  • cli/dispatcher/internal/dispatcher/launch_v2_server_ready_test.go

Comment thread cli/dispatcher/internal/dispatcher/launch_v2_lockfile.go
Comment thread cli/dispatcher/internal/dispatcher/launch_v2_server_ready.go
Comment thread cli/dispatcher/internal/dispatcher/launch_v2_server_ready.go
Store the wait timeout on v2ServerReadyTimeoutError so Details match
the call site, and stop the launch spinner before writing the existing-V2
readiness failure so stderr is not mixed with spinner frames.

Co-authored-by: Cursor <cursoragent@cursor.com>
Cover domainreload.lock busy waits, keep FailNow out of test
goroutines, stop the spinner on lockfile timeout, constantize the
loopback host, use V2-specific focus vibe logs, and warn when
previous sessionId read fails for a reason other than missing files.

Co-authored-by: Cursor <cursoragent@cursor.com>
@hatayama
hatayama merged commit 0f076fc into v3-beta Jul 27, 2026
12 checks passed
@hatayama
hatayama deleted the fix/v2-launch-server-readiness branch July 27, 2026 07:32
@github-actions github-actions Bot mentioned this pull request Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant