Skip to content

fix: keep pending WebSocket subscriptions across a reconnect - #19

Draft
chipkent wants to merge 1 commit into
masterfrom
fix/ws-keep-subscriptions-on-reconnect
Draft

chipkent wants to merge 1 commit into
masterfrom
fix/ws-keep-subscriptions-on-reconnect

Conversation

@chipkent

@chipkent chipkent commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Preview only. This is a draft in the fork showing the exact text of the PR planned for massive-com/client-python. It will be closed, not merged, once the upstream PR is opened.

Fixes #<issue: F2-keep>
Related to massive-com#800.

subscribe() only changes scheduled_subs. The receive loop sends the change on its next turn, up to a second later, and then copies it into subs, the topics sent.

1. Changes made just before a drop are lost. After an abnormal close, connect() ran self.scheduled_subs = set(self.subs) (from massive-com#207). That resubscribes what was sent, but throws away changes not sent yet: a topic subscribed just before the drop is missing afterwards, and a topic unsubscribed comes back. Now scheduled_subs is kept and only subs is reset.

2. Calling connect() again sends nothing. subs survived the earlier call, so after connect() returned (e.g. the server closed normally), the next call thought every topic was sent already. Each connect() now starts with empty subs and schedule_resub = True, so its first receive-loop turn sends everything in scheduled_subs. This is one way to get the missing subscriptions in massive-com#800.

client.subscribe("T.NVDA")  # the connection drops before it is sent
# before: reconnects without T.NVDA; now: with it

Tests

  • mock_server.py records each connection's messages (inbox) and drops the connection on DROP.X, like SLOW.X. BaseTest waits for the server, as StatusTest did.
  • New test_reconnect.py covers both bugs; both fail on master.
  • make test and make lint pass on 3.10 and 3.14.

Independent of the other PRs.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

subscribe() and unsubscribe() only change scheduled_subs, the topics
the caller wants. The receive loop sends the change on its next turn,
up to a second later, and then copies scheduled_subs into subs, the
topics the connection has been sent.

When the connection closed with an error, connect() set scheduled_subs
back to subs before reconnecting. That line came with "resub on
reconnect" (massive-com#207), and it does resubscribe the topics that were sent.
But a change made in the second before the drop had not been sent yet,
so it was thrown away: a topic subscribed just before the drop was
missing on the new connection, and a topic unsubscribed came back.

Keep scheduled_subs and only reset subs, so the new connection
subscribes to every topic the caller wants.

connect() also kept subs from an earlier call. Calling it again after
it returned, for example after the server closed the connection
cleanly, sent no subscribe message at all, because every topic looked
sent already. Reset subs at the start of every connect() call. This is
one way to end up with the missing subscriptions reported in massive-com#800.

The mock server now records the messages each connection receives, and
fails the connection on a DROP.X subscription. The shared test setup
waits for the server to start, as test_status did.
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