From 67472fbaa459e360291ee991dd4cb4496b7d34ba Mon Sep 17 00:00:00 2001 From: Yingliang Zhang Date: Wed, 1 Jul 2026 13:41:31 +0800 Subject: [PATCH] fix(tui_gateway): route setup.runtime_check and setup.status to RPC pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setup.runtime_check and setup.status are polled by the Desktop frontend on connect and periodically (use-status-snapshot → evaluateRuntimeReadiness), but neither was in _LONG_HANDLERS — so dispatch() ran both inline on the WS reader thread. Under GIL pressure from concurrent agent turns (terminal I/O, large output, background-process completions) either can block for seconds: - setup.runtime_check → resolve_runtime_provider() (config read, auth check, may probe the provider endpoint) - setup.status → _has_any_provider_configured() (provider config + credential scan) While either blocks the reader thread the WS read loop can't service later requests; the frontend RPC timeout fires, the client drops the socket, and the lost setup.runtime_check response reads as ready=false — a false "needs setup" / "Settings failed to load" even though the provider is configured. Route both to the RPC pool (same precedent as #55545's session.list/pet.info/ process.list). The handlers are read-only and pool writes go through the lock-guarded write_json, so there's no ordering or safety concern. Test asserts all 5 frontend-polled RPCs are pool-routed. Co-authored-by: izumi0uu --- tests/tui_gateway/test_inline_rpc_gil_starvation.py | 8 +++++--- tui_gateway/server.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/tui_gateway/test_inline_rpc_gil_starvation.py b/tests/tui_gateway/test_inline_rpc_gil_starvation.py index e9a01a76c58..80244b71a73 100644 --- a/tests/tui_gateway/test_inline_rpc_gil_starvation.py +++ b/tests/tui_gateway/test_inline_rpc_gil_starvation.py @@ -64,9 +64,11 @@ def capture(server): # seconds when the GIL is contended by concurrent agent turns. FRONTEND_POLLED_RPCS = [ - "session.list", # loads session list — SQLite query - "pet.info", # petdex poll — file/network read - "process.list", # background process status — process registry scan + "session.list", # loads session list — SQLite query + "pet.info", # petdex poll — file/network read + "process.list", # background process status — process registry scan + "setup.runtime_check", # runtime readiness — resolve_runtime_provider() I/O + "setup.status", # provider configured check — config/credential scan ] diff --git a/tui_gateway/server.py b/tui_gateway/server.py index faa09ff18c6..944d5273fd9 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -212,6 +212,16 @@ _LONG_HANDLERS = frozenset( "projects.for_cwd", "projects.tree", "projects.project_sessions", + # Setup readiness RPCs are polled by the Desktop frontend on connect + # and periodically (use-status-snapshot → evaluateRuntimeReadiness). + # setup.runtime_check calls resolve_runtime_provider() which reads + # config, checks auth state, and may probe the provider endpoint; + # setup.status calls _has_any_provider_configured() which scans + # provider config + credential files. Under GIL pressure from + # concurrent agent turns, either can take seconds inline, blocking + # the WS read loop and causing false "needs setup" (#50005 family). + "setup.runtime_check", + "setup.status", "session.branch", "session.compress", "session.list",