Skip to content

_runSub never resets _subRunning on a thrown connect/setup error — silently stops all fan-out on the process #62

Description

@bgeils

Summary

Stream._runSub sets this._subRunning = true on entry and only resets it at the natural end of the loop (src/stream.js:308-358 in v0.7.0). Two exits skip the reset:

  1. The initial redisSubscriptions.connect() throws (line ~315) — e.g. one DNS blip or a proxy closing the socket during connect.
  2. Any synchronous throw between the flag set and the loop.

After that, _subRunning stays true forever, every later subscribe() call sees "already running" and returns, and the process never delivers another stream message to any websocket subscriber — while continuing to accept connections and looking perfectly healthy. Clients complete their initial sync (served from getDoc) and then never receive another remote update.

Suggested fix

Wrap the loop in try/finally and reset the flag in finally; optionally split the subscription-client creation into a helper that clears this.redisSubscriptions and destroys the client on a failed connect so the next _runSub attempt starts clean:

async _runSub () {
  if (this._subRunning) return
  this._subRunning = true
  try {
    const redisSubscriptions = await this._getSubscriptionClient()
    while (this.subs.size > 0 || this.subUpdates.size > 0) { /* unchanged */ }
  } finally {
    this._subRunning = false
  }
}

We run this in production via a package patch and are happy to send a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions