diff options
author | Paul "LeoNerd" Evans <paul@matrix.org> | 2015-04-23 18:40:19 +0100 |
---|---|---|
committer | Paul "LeoNerd" Evans <paul@matrix.org> | 2015-04-23 18:40:19 +0100 |
commit | 8a785c3006327076245428d26e5ca1634e9caeb2 (patch) | |
tree | 344e0e077dbe0e1c1d54ed6bf9d436d0f5810075 /synapse/handlers/presence.py | |
parent | Generate presence event-stream JSON structures directly (diff) | |
download | synapse-8a785c3006327076245428d26e5ca1634e9caeb2.tar.xz |
Store a list of the presence serial number at which remote users went offline, so that when we delete them from the cachemap, we can still synthesize OFFLINE events for them (SYN-261)
Diffstat (limited to '')
-rw-r--r-- | synapse/handlers/presence.py | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py index 6332f50974..42fb622c48 100644 --- a/synapse/handlers/presence.py +++ b/synapse/handlers/presence.py @@ -135,6 +135,9 @@ class PresenceHandler(BaseHandler): self._remote_sendmap = {} # map remote users to sets of local users who're interested in them self._remote_recvmap = {} + # list of (serial, set of(userids)) tuples, ordered by serial, latest + # first + self._remote_offline_serials = [] # map any user to a UserPresenceCache self._user_cachemap = {} @@ -715,6 +718,10 @@ class PresenceHandler(BaseHandler): ) if state["presence"] == PresenceState.OFFLINE: + self._remote_offline_serials.insert( + 0, + (self._user_cachemap_latest_serial, set([user.to_string()])) + ) del self._user_cachemap[user] for poll in content.get("poll", []): @@ -856,6 +863,20 @@ class PresenceEventSource(object): # TODO(paul): limit + for serial, user_ids in presence._remote_offline_serials: + if serial < from_key: + break + + for u in user_ids: + updates.append({ + "type": "m.presence", + "content": {"user_id": u, "presence": PresenceState.OFFLINE}, + }) + # TODO(paul): For the v2 API we want to tell the client their from_key + # is too old if we fell off the end of the _remote_offline_serials + # list, and get them to invalidate+resync. In v1 we have no such + # concept so this is a best-effort result. + if updates: defer.returnValue((updates, latest_serial)) else: |