Yet another try at fixing presence endless loop

This commit is contained in:
miruka 2021-04-17 07:40:27 -04:00
parent 86c0cb1bf2
commit 22bce261d3
2 changed files with 20 additions and 9 deletions

View File

@ -205,6 +205,7 @@ class MatrixClient(nio.AsyncClient):
self.first_sync_done: asyncio.Event = asyncio.Event() self.first_sync_done: asyncio.Event = asyncio.Event()
self.first_sync_date: Optional[datetime] = None self.first_sync_date: Optional[datetime] = None
self.last_sync_error: Optional[Exception] = None self.last_sync_error: Optional[Exception] = None
self.last_set_presence: datetime = datetime.now()
self.past_tokens: Dict[str, str] = {} # {room_id: token} self.past_tokens: Dict[str, str] = {} # {room_id: token}
self.fully_loaded_rooms: Set[str] = set() # {room_id} self.fully_loaded_rooms: Set[str] = set() # {room_id}

View File

@ -868,13 +868,22 @@ class NioCallbacks:
# Presence event callbacks # Presence event callbacks
async def onPresenceEvent(self, ev: nio.PresenceEvent) -> None: async def onPresenceEvent(
self, ev: Union[nio.PresenceEvent, nio.PresenceGetResponse],
) -> None:
# Servers that send presence events support presence # Servers that send presence events support presence
self.models["accounts"][self.client.user_id].presence_support = True self.models["accounts"][self.client.user_id].presence_support = True
account = self.models["accounts"].get(ev.user_id) account = self.models["accounts"].get(ev.user_id)
presence = self.client.backend.presences.get(ev.user_id, Presence()) presence = self.client.backend.presences.get(ev.user_id, Presence())
if account:
client = self.client.backend.clients[ev.user_id]
# Synapse is stupid enough to return an older presence state on
# sync, which then causes a never-ending loop of presence cycling.
# Let's hope they didn't screw up the get_presence API too:
ev = await client.get_presence(ev.user_id)
presence.currently_active = ev.currently_active or False presence.currently_active = ev.currently_active or False
presence.status_msg = ev.status_msg or "" presence.status_msg = ev.status_msg or ""
@ -885,10 +894,7 @@ class NioCallbacks:
else: else:
presence.last_active_at = datetime.fromtimestamp(0) presence.last_active_at = datetime.fromtimestamp(0)
if ev.presence: presence.presence = Presence.State(ev.presence)
presence.presence = Presence.State(ev.presence)
else:
presence.presence = Presence.State.offline
# Add all existing members related to this presence # Add all existing members related to this presence
for room_id in self.models[self.user_id, "rooms"]: for room_id in self.models[self.user_id, "rooms"]:
@ -901,6 +907,8 @@ class NioCallbacks:
# If presence event represents a change for one of our account # If presence event represents a change for one of our account
if account and account.presence != Presence.State.offline: if account and account.presence != Presence.State.offline:
client = self.client.backend.clients[ev.user_id]
# Ignore cases where we send a new presence to the server, but it # Ignore cases where we send a new presence to the server, but it
# returns an older state that doesn't match due to lag: # returns an older state that doesn't match due to lag:
if ( if (
@ -921,13 +929,11 @@ class NioCallbacks:
# only possible if we're the only client using the account, or the # only possible if we're the only client using the account, or the
# other clients are invisible/offline themselves. # other clients are invisible/offline themselves.
if ev.presence != Presence.State.offline.value: if ev.presence != Presence.State.offline.value:
self.client.backend.clients[ev.user_id]._presence = ev.presence client._presence = ev.presence
# Restore status msg lost from server due to e.g. getting offline # Restore status msg lost from server due to e.g. getting offline
if not ev.status_msg and account.status_msg: if not ev.status_msg and account.status_msg:
await self.client.backend.clients[ev.user_id].set_presence( await client.set_presence(ev.presence, account.status_msg)
ev.presence, account.status_msg,
)
# Save the presence to be restored next time we restart application # Save the presence to be restored next time we restart application
if account.save_presence: if account.save_presence:
@ -937,6 +943,10 @@ class NioCallbacks:
if account.presence == Presence.State.echo_invisible: if account.presence == Presence.State.echo_invisible:
status_msg = account.status_msg status_msg = account.status_msg
state = Presence.State.invisible state = Presence.State.invisible
elif state == Presence.State.echo_online:
state = Presence.State.online
elif state == Presence.State.echo_unavailable:
state = Presence.State.unavailable
await self.client.backend.saved_accounts.set( await self.client.backend.saved_accounts.set(
user_id = ev.user_id, user_id = ev.user_id,