Skip to content

fix(desktop): own native WebSocket lifecycle#2076

Merged
tlongwell-block merged 4 commits into
mainfrom
max/native-websocket-lifecycle
Jul 18, 2026
Merged

fix(desktop): own native WebSocket lifecycle#2076
tlongwell-block merged 4 commits into
mainfrom
max/native-websocket-lifecycle

Conversation

@tlongwell-block

Copy link
Copy Markdown
Collaborator

Summary

  • replace tauri-plugin-websocket with a small Buzz-owned tokio-tungstenite lifecycle adapter
  • isolate each connection behind a bounded queue and cancellable owner task, with native connect/write deadlines and EOF/error cleanup
  • add authoritative disconnect / disconnect_all commands and tear down native sockets before Cmd+R reload
  • register explicit Tauri ACL permissions and update the browser test bridge

Why

The upstream plugin keeps every writer behind one global mutex, awaits network I/O while holding it, has no force-disconnect command, and can retain native sockets across webview reload. A half-open transport can therefore survive JS reset/reload and block unrelated connections.

This is lifecycle hardening, not a claim that it was the proven root cause of Mat's report: Mat was on 0.4.16 before #2060, and the observed trigger aligns with a relay pod bounce.

Validation

  • just ci (Hermit Rust 1.95): pass
  • Desktop Tauri suite: 1471 passed, 13 ignored
  • Desktop JS suite: 3158 passed
  • focused native lifecycle tests: EOF cleanup, bounded/idempotent forced shutdown, cross-connection queue isolation, teardown gate ordering
  • independent red-team found three blockers; fixed the TS resurrection-prone approach by dropping ordered per-client awaits, held native connect gate through disconnect_all, and added the inlined-plugin ACL/default permission
  • generated ACL confirms websocket:default allows connect/send/disconnect/disconnect_all

Not run

  • signed/package release build: requires real bundled sidecar artifacts; compile, clippy, unit, frontend build, and generated ACL all ran locally

Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
@tlongwell-block
tlongwell-block requested a review from a team as a code owner July 18, 2026 17:42
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No code-level blocker found in the native WebSocket lifecycle implementation. I checked cancellation/gating, bounded queues and shutdown, stale-connection cleanup, frontend IPC compatibility, ACL registration, reload teardown, and the added Rust/JS/E2E coverage.

I’m holding approval because this head (3633663fe) is behind current main and required CI is not green: Desktop E2E Integration is failing in the newer onboarding membership-denial/import flow, while several smoke shards are still running. The failure appears unrelated to this WebSocket diff, so please sync current main and rerun CI; I can approve once the updated head is green.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Implementation review is clean. Approving so this can merge after the branch is synced as needed and required CI is green.

@tlongwell-block
tlongwell-block enabled auto-merge (squash) July 18, 2026 18:05
@tlongwell-block
tlongwell-block disabled auto-merge July 18, 2026 18:06
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
@tlongwell-block
tlongwell-block enabled auto-merge (squash) July 18, 2026 18:28
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
@tlongwell-block
tlongwell-block merged commit 4cf5694 into main Jul 18, 2026
25 checks passed
@tlongwell-block
tlongwell-block deleted the max/native-websocket-lifecycle branch July 18, 2026 18:52
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.

2 participants