fix(api): make TeslemetryStream.close() abort the active SSE stream - #83
Conversation
close() previously only flipped active=false; the in-flight fetch/reader and any pending reconnect backoff timer (up to 10 min) kept running, leaking HTTP streams and timers on teardown/reinit. close()/disconnect() now abort via a per-connect AbortController shared by the fetch signal and the backoff wait, and are awaitable so callers can sequence teardown before reconnecting.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5bce234bd9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| this.abortController = new AbortController(); | ||
| this.loopPromise = this._connectLoop(this.abortController.signal); |
There was a problem hiding this comment.
Prevent reconnects before the prior loop exits
When a caller uses the formerly synchronous API as close(); connect() without awaiting the new close promise, connect() sets the shared active flag back to true before the aborted old loop resumes. That old _connectLoop then keeps iterating with its permanently aborted signal; each generated SSE stream ends immediately, so the outer loop can spin continuously, emit spurious connect events, consume CPU, and prevent the close promise from settling while the new loop also runs. Serialize reconnects or make loop continuation depend on per-loop ownership rather than the shared active flag.
Useful? React with 👍 / 👎.
Intent
TeslemetryStream.close()only setactive = false; the in-flight SSE fetch/reader and any pending reconnect backoff timer (up to 10 minutes) kept running past teardown, leaking HTTP streams and timers on reinit.connect()now creates a per-connectionAbortControllerand threads its signal into the generated SSE client'ssignaloption and into the reconnect backoff wait, soclose()can cancel both immediately instead of waiting for them to time out or fire.close()/disconnect()are nowasyncand resolve once_connectLoophas fully exited, so callers canawait close()before reconnecting without a leak window.connect()afterclose()reinitializes cleanly.@teslemetry/api) per the repo's release flow.@teslemetry/apipin and reinstall/build/test against it. Not done here - the homey app lives in a separate repo, and the new version doesn't exist on npm until this merges and the changesets release flow runs.