Skip to content

🐛 Only call _subscribe once for concurrent subscribes to a channel - #753

Merged
alecgibson merged 1 commit into
mainfrom
coalesce-concurrent-subscribes
Oct 9, 2026
Merged

alecgibson merged 1 commit into
mainfrom
coalesce-concurrent-subscribes

Conversation

@alecgibson

Copy link
Copy Markdown
Collaborator

Fixes #739

At the moment, PubSub.subscribe() only marks a channel as subscribed once _subscribe() calls back, so any other subscribe to that channel in the meantime calls _subscribe() again. sharedb-redis-pubsub adds a listener per call, so every op is delivered once per listener.

This change queues concurrent subscribers behind the in-flight _subscribe(). We create all of their streams before calling any callback, since Agent can destroy a presence stream from inside its callback, which would otherwise unsubscribe the channel from under the subscribers still waiting.

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Fixes #739

At the moment, `PubSub.subscribe()` only marks a channel as subscribed
once `_subscribe()` calls back, so any other subscribe to that channel
in the meantime calls `_subscribe()` again. `sharedb-redis-pubsub` adds
a listener per call, so every op is delivered once per listener.

This change queues concurrent subscribers behind the in-flight
`_subscribe()`. We create all of their streams before calling any
callback, since `Agent` can destroy a presence stream from inside its
callback, which would otherwise unsubscribe the channel from under the
subscribers still waiting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 97.855% (+0.004%) from 97.851% — coalesce-concurrent-subscribes into main

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation resolves duplicate adapter subscriptions and covers the relevant concurrency edge cases.

0 open findings

What changed in this PR

Queues concurrent channel subscriptions so only one adapter-level _subscribe call occurs.

Changes:

  • Tracks in-flight subscriptions per channel.
  • Creates all queued streams before invoking callbacks.
  • Adds success, failure, teardown, and retry coverage.
File Description
lib/​pubsub/​index.js Coalesces concurrent subscriptions.
test/​pubsub.js Tests delivery and stream destruction behavior.
test/​pubsub-memory.js Tests errors, retries, and resubscription.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@alecgibson
alecgibson marked this pull request as ready for review October 9, 2026 09:46
@alecgibson
alecgibson requested a review from dawidreedsy October 9, 2026 09:46
@alecgibson
alecgibson merged commit 3446273 into main Oct 9, 2026
9 checks passed
@alecgibson
alecgibson deleted the coalesce-concurrent-subscribes branch October 9, 2026 14:19
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.

Concurrent subscribes to a new channel each call _subscribe

4 participants