Skip to content

fix: inject tokio runtime handle into sync watch* spawn#281

Open
dignifiedquire wants to merge 2 commits into
mainfrom
fix/watch-async
Open

fix: inject tokio runtime handle into sync watch* spawn#281
dignifiedquire wants to merge 2 commits into
mainfrom
fix/watch-async

Conversation

@dignifiedquire

Copy link
Copy Markdown
Contributor

Closes #277

The sync watch_* registration methods spawn a background task via
tokio::spawn, but they run on the foreign caller's thread with no
tokio Handle in TLS — causing 'no reactor running' panics that abort
the JS host process and surface as uniffi InternalException.

- JS: spawn via napi::bindgen_prelude::spawn, which uses napi's own
  global tokio runtime — no state threading needed.
- Uniffi: capture Handle::current() at Endpoint / Connection
  construction (all callers are async fns wrapped by async_compat)
  and pass it to the spawn helpers.

Both approaches keep the sync fire-and-forget API — the fn signature
does not become async.
Register + stop each watch_* method — before the runtime-handle fix
these panicked with 'no reactor running', aborting the JS host and
surfacing as InternalException on Python/Kotlin/Swift.

Coverage: Rust (std::thread — reproduces the FFI thread condition),
JS (node:test), Python (pytest), Kotlin (JUnit), Swift (XCTest).
@emin93

emin93 commented Jul 20, 2026

Copy link
Copy Markdown

Reviewed — routing the watcher spawns through the runtime handle resolves the panic at its actual root (spawn-time ambient-runtime assumption), and fixing it in the shared core rather than per-binding is the right call: we'd reproduced the failure on three surfaces (napi aborts the process, Kotlin surfaces InternalException), and the test additions cover all of them plus Python. Once released we can retire our poll-only workaround and get push semantics back for relay/path status — which we currently approximate with heartbeat timeouts. Looks good, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🚑 Needs Triage

Development

Successfully merging this pull request may close these issues.

JS bindings: watch* APIs panic 'no reactor running' and abort the host process

2 participants