Fix graceful websocket reconnect and release 0.2.2 - #13
Merged
Merged
Conversation
Refs #12. Restore subscriptions after EOF and make retry waits interruptible by close.
8 tasks
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.
Summary
A graceful websocket EOF left all three venue clients reporting healthy and repeatedly reading the exhausted stream without backoff. Polymarket, Kalshi, and Opinion now mark the connection down, increment reconnect_count once, wait for backoff, reconnect and restore the saved subscription. Opinion stops its old heartbeat before waiting and starts a new one after connecting.
Explicit close interrupts retry waits. Cancelling or closing the message iterator releases the socket/heartbeat without reconnecting; repeated close is safe, and explicit connect starts a new session. Prepare patch release 0.2.2, with CHANGELOG and lifecycle/agent documentation.
Refs #12. Keep the issue open until public PyPI installation and artifact identity verification succeed.
Validation
uv sync --group devuv run ruff check .uv run mypy— 25 source filesuv run pytest -q -s— 94 passed, including 36 new lifecycle regression casesuv builduv run twine check dist/*— wheel and sdist passeduv run mkdocs build --strictgit diff --checkThe three graceful-EOF cases fail on baseline 0.2.1 (
80d80a0556cb30d8c4622cc6c92c2f980822d59b) with a bounded assertion detecting repeated reads of an exhausted socket; they pass on this change. Tests cover normal EOF, transport errors, exact backoff/reconnect/subscription counts, health, Opinion heartbeat replacement, raw payloads, close/cancel/manager stop during idle reads and one-hour retry waits, repeated close, explicit restart, and close during connection establishment.Exact commit
0c60aa9b95fc9fb47ad8c8d8b289a72460bc506fpassed the full gate in a cleangit clone --no-localon Python 3.12 (94 passed; clean before/after). The worktree gate also passed on Python 3.14. Separate fresh Python 3.12 environments installed the wheel and sdist, verified public imports and version, and each passed all 36 regressions with current public dependencies, including websockets 17.1.Boundary
Only predxt changes are included. PyPI publication remains a separate release.yml Trusted Publishing step after CI and merge.