Summary
Connection.getDocPresence caches presence by channel, and a doc's channel is collection + '.' + id. Docs whose names contain dots can share a channel, so the second caller silently gets the first doc's instance:
connection.getDocPresence('notes', 'private.alice');
connection.getDocPresence('notes.private', 'alice'); // collection 'notes', id 'private.alice'
Local presence created on the second one is sent for notes/private.alice, and transformed against that doc's ops. The same cache means getDocPresence after getPresence on the same channel string returns the untyped Presence, and vice versa.
With #752, a DocPresence ignores presence for any other doc, so nothing crosses between the two docs over the wire. But the two docs still can't both have presence on one connection.
Suggested fix
The cache, message dispatch (Connection._handlePresence looks up _presences[message.ch]) and server-side presence subscriptions are all keyed by channel, so two docs sharing a channel can't be told apart without an unambiguous channel name, such as escaping dots in DocPresence.channel.
Every client and server builds that same string, though, and since #752 the server rejects doc presence whose channel doesn't match it. So any change to the channel format has to be accepted in both formats on the server, depending on the client's protocol version (agent.protocol), so that mixed-version clients keep working.
A cheaper first step: make getDocPresence throw when the cached instance isn't a DocPresence for the requested doc, rather than silently returning it.
Summary
Connection.getDocPresencecaches presence by channel, and a doc's channel iscollection + '.' + id. Docs whose names contain dots can share a channel, so the second caller silently gets the first doc's instance:Local presence created on the second one is sent for
notes/private.alice, and transformed against that doc's ops. The same cache meansgetDocPresenceaftergetPresenceon the same channel string returns the untypedPresence, and vice versa.With #752, a
DocPresenceignores presence for any other doc, so nothing crosses between the two docs over the wire. But the two docs still can't both have presence on one connection.Suggested fix
The cache, message dispatch (
Connection._handlePresencelooks up_presences[message.ch]) and server-side presence subscriptions are all keyed by channel, so two docs sharing a channel can't be told apart without an unambiguous channel name, such as escaping dots inDocPresence.channel.Every client and server builds that same string, though, and since #752 the server rejects doc presence whose channel doesn't match it. So any change to the channel format has to be accepted in both formats on the server, depending on the client's protocol version (
agent.protocol), so that mixed-version clients keep working.A cheaper first step: make
getDocPresencethrow when the cached instance isn't aDocPresencefor the requested doc, rather than silently returning it.