Skip to content

A presence that finishes after a newer one can still outlive its client #763

Open

Description

@alecgibson

Summary

This follows up #748, which #751 fixes for presence that is still in middleware when its client leaves.

Agent._broadcastPresence only stores a presence in presenceRequests if its pv is newer than the stored one, but it publishes the presence either way. So an older presence that gets through receivePresence middleware after a newer one with the same id is published without being tracked anywhere. It is already out of _pendingPresenceBroadcasts, and it never enters presenceRequests. If the client unsubscribes or disconnects while that presence is still being transformed or published, the leave can't turn it into null.

Remote clients normally drop it by pv. But if the leave reaches them first, Presence._updateRemotePresence destroys the RemotePresence, and its pv goes with it. A fresh RemotePresence then accepts the stale value. After a disconnect, nothing ever clears it.

Reproduction

  1. Client A submits doc presence twice in quick succession with the same id (pv 1, then pv 2).
  2. receivePresence middleware holds pv 1 until pv 2 has been published.
  3. pv 1 is released and moves on to its transform (for example, a slow getOps).
  4. Client A disconnects while pv 1 is still being transformed. If the leave is published first, client B receives null, then pv 1, and keeps showing A's presence.

Suggested fix

After middleware, don't publish a presence whose pv is older than the stored one for its id; just acknowledge it to the client. Remote clients have already seen the newer presence, or are about to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions