Faster room joins: Fix spurious error when joining a room (#13872)

During a `lazy_load_members` `/sync`, we look through auth events in
rooms with partial state to find prior membership events. When such a
membership is not found, an error is logged.

Since the first join event for a user never has a prior membership event
to cite, the error would always be logged when one appeared in the room
timeline.

Avoid logging errors for such events.

Introduced in #13477.

Signed-off-by: Sean Quah <seanq@matrix.org>
This commit is contained in:
Sean Quah 2022-09-27 11:17:23 +01:00 committed by GitHub
parent d6b85a2a7d
commit 85e161631a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 3 deletions

1
changelog.d/13872.bugfix Normal file
View File

@ -0,0 +1 @@
Faster room joins: Fix a bug introduced in 1.66.0 where an error would be logged when syncing after joining a room.

View File

@ -1191,7 +1191,9 @@ class SyncHandler:
room_id: The partial state room to find the remaining memberships for. room_id: The partial state room to find the remaining memberships for.
members_to_fetch: The memberships to find. members_to_fetch: The memberships to find.
events_with_membership_auth: A mapping from user IDs to events whose auth events_with_membership_auth: A mapping from user IDs to events whose auth
events are known to contain their membership. events would contain their prior membership, if one exists.
Note that join events will not cite a prior membership if a user has
never been in a room before.
found_state_ids: A dict from (type, state_key) -> state_event_id, containing found_state_ids: A dict from (type, state_key) -> state_event_id, containing
memberships that have been previously found. Entries in memberships that have been previously found. Entries in
`members_to_fetch` that have a membership in `found_state_ids` are `members_to_fetch` that have a membership in `found_state_ids` are
@ -1201,6 +1203,10 @@ class SyncHandler:
A dict from ("m.room.member", state_key) -> state_event_id, containing the A dict from ("m.room.member", state_key) -> state_event_id, containing the
memberships missing from `found_state_ids`. memberships missing from `found_state_ids`.
When `events_with_membership_auth` contains a join event for a given user
which does not cite a prior membership, no membership is returned for that
user.
Raises: Raises:
KeyError: if `events_with_membership_auth` does not have an entry for a KeyError: if `events_with_membership_auth` does not have an entry for a
missing membership. Memberships in `found_state_ids` do not need an missing membership. Memberships in `found_state_ids` do not need an
@ -1218,8 +1224,18 @@ class SyncHandler:
if (EventTypes.Member, member) in found_state_ids: if (EventTypes.Member, member) in found_state_ids:
continue continue
missing_members.add(member)
event_with_membership_auth = events_with_membership_auth[member] event_with_membership_auth = events_with_membership_auth[member]
is_join = (
event_with_membership_auth.is_state()
and event_with_membership_auth.type == EventTypes.Member
and event_with_membership_auth.state_key == member
and event_with_membership_auth.content.get("membership")
== Membership.JOIN
)
if not is_join:
# The event must include the desired membership as an auth event, unless
# it's the first join event for a given user.
missing_members.add(member)
auth_event_ids.update(event_with_membership_auth.auth_event_ids()) auth_event_ids.update(event_with_membership_auth.auth_event_ids())
auth_events = await self.store.get_events(auth_event_ids) auth_events = await self.store.get_events(auth_event_ids)
@ -1243,7 +1259,7 @@ class SyncHandler:
auth_event.type == EventTypes.Member auth_event.type == EventTypes.Member
and auth_event.state_key == member and auth_event.state_key == member
): ):
missing_members.remove(member) missing_members.discard(member)
additional_state_ids[ additional_state_ids[
(EventTypes.Member, member) (EventTypes.Member, member)
] = auth_event.event_id ] = auth_event.event_id