fix(gateway): bound wake recovery and release stalled writer resources - #1780
Merged
Merged
Conversation
Open-Squilla
enabled auto-merge
September 21, 2026 00:04
Open-Squilla
disabled auto-merge
September 21, 2026 00:15
|
Merge queue CI: success — run 35590649545, attempt 1. The run summary lists reused suites and executed checks. A green PR check alone does not mean queue validation has passed. |
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.
Scope
Scope boundary: A half-open Gateway connection can remain apparently connected after wake, and repeated resume/pageshow/online signals can indefinitely postpone recovery. Bound each connection generation to a fixed 20-second wake incident, fence recovery by generation/nonce/pending ownership, expose suspect health in the existing UI, and fail ordinary calls once suspect. Preserve recovery from a controlled 13-second pause.
Writer cleanup releases reservations on serialization failure and cancellation, reports capacity/close reasons, and routes direct-send timeouts through the bounded close coordinator. A stalled close cancels its owning ASGI handler so registry cleanup and transport teardown can complete. Review also fixed callback reentrancy, wake incorrectly clearing an existing suspect state, and Vue proxy object identity preventing deadline retirement in the native Desktop store.
Non-goals: No protocol change, flow-window/512-slot adjustment, pong deduplication, renderer reload, or change to the existing direct-send/recovery-credit/queued-send 2/30/60-second resource limits.
Branch
Base branch: main
Target exception: N/A
Issue
Linked issue: None
If None, reason: Maintainer-requested Gateway wake and writer stability investigation and implementation.
Release Note
Release note: Recover stalled Gateway connections after wake within a fixed incident budget, show connection recovery in the UI, and reliably release writer resources during failures.
Tests
Ruff: passed for src, tests, and the new Python harness.
Pytest: 148 targeted Gateway tests passed. Broader Windows Gateway run: 5,512 passed and 22 skipped, with one obsolete code-only WebSocket test double subsequently fixed and verified in the targeted run. Five unrelated Windows environment failures reproduce unchanged on origin/main (four symlink-privilege cases; one installed-MiKTeX test-isolation case).
Build: final Vue proxy implementation passed all 7,693 WebUI unit tests in CI; local RPC/store/connection integration passed 187 tests, including new Vue proxy and reentrant callback regressions. Full architecture/type checks, production artifact build and Electron build passed; final Vue type check/build passed; mypy passed across 1,643 source files.
Regression tests: added
Notes: Integration baseline c31abea, fetched again after final local validation. Final-source Vue-proxied browser relay matrix: 300 trials, 30 per cell, independently recomputed. Single wake recovery p50 improved from 47.4431 s to 20.4167 s (p95 20.5288 s, max 20.5612 s); repeated-wake baseline trials stayed unrecovered at 90 s while the candidate recovered in every trial. Both versions preserved all controlled 13-second pauses. Writer matrix: 210 trials, all assertions passed and final connection/global budgets and writer/close task counts zero. Browser recovery/Goal/steer/hydration E2E: 44 passed.
Windows source Electron initially exposed the Vue proxy bug; after fixing it, the rerun passed with suspect UI at 15.938 s and a successful replacement RPC observed at 20.413 s. Seven resume signals shared one incident, one replacement was accepted, and draft/renderer ownership stayed intact. This is one source Electron run with application-frame fault injection, not physical sleep or packaged reliability evidence.
An additional Windows packaged-app wake test passed using the hash-verified NSIS payload from run 35546427479 (CI merge 6c81eb2, containing ddddce6 + c31abea). The local harness asserted app.isPackaged and the executable path, ran from an isolated temporary profile, and recorded suspect UI at 15.947 s, recovered RPC at 20.623 s, one replacement, retained renderer/draft, and normal 2.301 s shutdown. This is one loopback application-frame fault injection; no physical sleep, full installer registration, or 30-cycle business acceptance is implied. Subsequent 5e2248f changes only the independent Python test driver and tests.
Reproduction and full results: docs/gateway-stability/README.md and VALIDATION.zh-CN.md. Historical 675/8c7/v0.5.4 and earlier raw-client measurements are not final acceptance. The 20-second budget is provisional, not proven optimal. Real physical sleep, true remote/VPN faults, packaged Windows 30-cycle reliability, and packaged Goal/mutation exactly-once acceptance are not claimed.
Full CI run 35546427479 passed all Windows NSIS installation/upgrade cells and 151 browser recovery E2E tests, but failed two tests. The existing fault driver selected and released its Gateway port before the fault proxy bound, permitting a deterministically reproduced collision and false health readiness; first port selection now occurs after proxy startup, with restart port continuity retained. The new writer timeout test also charged synchronous exception rendering to its 500 ms watchdog; it now captures and asserts structured timeout diagnostics while retaining the same timeout and resource assertions. The original CI exception in the fault driver was sanitized, so its exact historical cause remains unproven. Final-head CI 35547976133 passed all jobs. Independent read-only review found no new actionable issues in these fixes.
The default test path remains offline, deterministic, credential-free, and safe for forks.
Maintainer Live Check
Maintainer live check: no
Surface: gateway
Safety
Only source, synthetic tests, reproduction scripts and portable documentation are included. Raw local evidence archives, profiles, credentials, payloads and private transcripts are excluded.
Third-Party Origin
Third-party origin: none
Documentation Changes