Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Track presence state per-device and combine to a user state. (#16066)
Browse files Browse the repository at this point in the history
Tracks presence on an individual per-device basis and combine
the per-device state into a per-user state. This should help in
situations where a user has multiple devices with conflicting status
(e.g. one is syncing with unavailable and one is syncing with online).

The tie-breaking is done by priority:

    BUSY > ONLINE > UNAVAILABLE > OFFLINE
  • Loading branch information
clokep committed Sep 5, 2023
1 parent 1a7c43a commit 1468cbb
Show file tree
Hide file tree
Showing 7 changed files with 765 additions and 61 deletions.
1 change: 1 addition & 0 deletions changelog.d/16066.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where multi-device accounts could cause high load due to presence.
1 change: 1 addition & 0 deletions changelog.d/16170.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where multi-device accounts could cause high load due to presence.
1 change: 1 addition & 0 deletions changelog.d/16171.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where multi-device accounts could cause high load due to presence.
1 change: 1 addition & 0 deletions changelog.d/16172.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug where multi-device accounts could cause high load due to presence.
43 changes: 39 additions & 4 deletions synapse/api/presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,53 @@
from synapse.types import JsonDict


@attr.s(slots=True, auto_attribs=True)
class UserDevicePresenceState:
"""
Represents the current presence state of a user's device.
user_id: The user ID.
device_id: The user's device ID.
state: The presence state, see PresenceState.
last_active_ts: Time in msec that the device last interacted with server.
last_sync_ts: Time in msec that the device last *completed* a sync
(or event stream).
"""

user_id: str
device_id: Optional[str]
state: str
last_active_ts: int
last_sync_ts: int

@classmethod
def default(
cls, user_id: str, device_id: Optional[str]
) -> "UserDevicePresenceState":
"""Returns a default presence state."""
return cls(
user_id=user_id,
device_id=device_id,
state=PresenceState.OFFLINE,
last_active_ts=0,
last_sync_ts=0,
)


@attr.s(slots=True, frozen=True, auto_attribs=True)
class UserPresenceState:
"""Represents the current presence state of the user.
user_id
last_active: Time in msec that the user last interacted with server.
last_federation_update: Time in msec since either a) we sent a presence
user_id: The user ID.
state: The presence state, see PresenceState.
last_active_ts: Time in msec that the user last interacted with server.
last_federation_update_ts: Time in msec since either a) we sent a presence
update to other servers or b) we received a presence update, depending
on if is a local user or not.
last_user_sync: Time in msec that the user last *completed* a sync
last_user_sync_ts: Time in msec that the user last *completed* a sync
(or event stream).
status_msg: User set status message.
currently_active: True if the user is currently syncing.
"""

user_id: str
Expand Down
Loading

0 comments on commit 1468cbb

Please sign in to comment.