Skip to content

WebSocket: disconnect() sends pending subscribe and unsubscribe calls - #23

Merged
0xFantomMenace merged 1 commit into
masterfrom
fix/ws-pending-sends
Oct 8, 2026
Merged

0xFantomMenace merged 1 commit into
masterfrom
fix/ws-pending-sends

Conversation

@0xFantomMenace

Copy link
Copy Markdown
Member

subscribe() and unsubscribe() send their frames from background tasks. Two problems:

  • The tasks were not kept, and asyncio holds tasks only by weak reference.
  • disconnect() closed the socket without waiting for them. An unsubscribe() followed by disconnect() could therefore fail against the closed connection and log Task exception was never retrieved.

Changes:

  • Background sends are kept until they finish.
  • disconnect() flushes them first, waiting up to 2 seconds.
  • A send that finds the connection already closed is dropped quietly, since the server forgets a closed connection's subscriptions. Any other failure goes to the on_error handler.

Tested:

  • tests/test_websocket_sends.py: three tests. All three fail on master and pass here.
  • The full suite passes (504 passed, 17 skipped).
  • ruff and mypy findings are unchanged from master.
  • Live against wss://stream.0xarchive.io/ws: three subscribe, unsubscribe and disconnect() cycles, with no loop errors and no unsent frames left.

Part of the unreleased 1.13.0 (CHANGELOG "Fixed").

@0xFantomMenace
0xFantomMenace merged commit 48db704 into master Oct 8, 2026
1 check passed
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.

1 participant