Summary
Every p: null doc presence broadcast reads the op log, only to advance the presence's v.
Agent._broadcastPresence handles a null presence by calling _unsubscribeDocVersion first, which clears latestDocVersions[c][d]. The up-to-date check that follows compares against that cleared value, so a null doc presence never counts as up to date. It always goes through Backend.transformPresenceToLatestVersion, which runs getOps from the presence's last v to the latest version, and then op middleware on each op.
If a cursor sat idle on a busy doc, that read can be long. A mass disconnect, such as a deploy or a load balancer drain, turns every open doc presence into one of these reads at the same time.
The presence still needs a current v. A null presence with an old v makes the receiving client fetch the doc and wait for ops to catch up (RemoteDocPresence), so skipping the transform outright isn't enough.
Suggested fix
Give a null presence the doc's current version from a snapshot or version read, rather than replaying ops to transform a value that is null anyway.
Summary
Every
p: nulldoc presence broadcast reads the op log, only to advance the presence'sv.Agent._broadcastPresencehandles anullpresence by calling_unsubscribeDocVersionfirst, which clearslatestDocVersions[c][d]. The up-to-date check that follows compares against that cleared value, so anulldoc presence never counts as up to date. It always goes throughBackend.transformPresenceToLatestVersion, which runsgetOpsfrom the presence's lastvto the latest version, and thenopmiddleware on each op.If a cursor sat idle on a busy doc, that read can be long. A mass disconnect, such as a deploy or a load balancer drain, turns every open doc presence into one of these reads at the same time.
The presence still needs a current
v. Anullpresence with an oldvmakes the receiving client fetch the doc and wait for ops to catch up (RemoteDocPresence), so skipping the transform outright isn't enough.Suggested fix
Give a
nullpresence the doc's current version from a snapshot or version read, rather than replaying ops to transform a value that isnullanyway.