Fix sliding sync for rooms with unknown room version (#17733)
Follow on from #17727
This commit is contained in:
parent
83fc225030
commit
07a51d2a56
|
@ -0,0 +1 @@
|
||||||
|
Fix a bug in SSS which could prevent /sync from working for certain user accounts.
|
|
@ -40,6 +40,7 @@ from synapse.api.constants import (
|
||||||
EventTypes,
|
EventTypes,
|
||||||
Membership,
|
Membership,
|
||||||
)
|
)
|
||||||
|
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
||||||
from synapse.events import StrippedStateEvent
|
from synapse.events import StrippedStateEvent
|
||||||
from synapse.events.utils import parse_stripped_state_event
|
from synapse.events.utils import parse_stripped_state_event
|
||||||
from synapse.logging.opentracing import start_active_span, trace
|
from synapse.logging.opentracing import start_active_span, trace
|
||||||
|
@ -952,6 +953,15 @@ class SlidingSyncRoomLists:
|
||||||
excluded_rooms=self.rooms_to_exclude_globally,
|
excluded_rooms=self.rooms_to_exclude_globally,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# We filter out unknown room versions before we try and load any
|
||||||
|
# metadata about the room. They shouldn't go down sync anyway, and their
|
||||||
|
# metadata may be in a broken state.
|
||||||
|
room_for_user_list = [
|
||||||
|
room_for_user
|
||||||
|
for room_for_user in room_for_user_list
|
||||||
|
if room_for_user.room_version_id in KNOWN_ROOM_VERSIONS
|
||||||
|
]
|
||||||
|
|
||||||
# Remove invites from ignored users
|
# Remove invites from ignored users
|
||||||
ignored_users = await self.store.ignored_users(user_id)
|
ignored_users = await self.store.ignored_users(user_id)
|
||||||
if ignored_users:
|
if ignored_users:
|
||||||
|
|
|
@ -41,6 +41,7 @@ import attr
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership
|
||||||
from synapse.api.errors import Codes, SynapseError
|
from synapse.api.errors import Codes, SynapseError
|
||||||
|
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
||||||
from synapse.logging.opentracing import trace
|
from synapse.logging.opentracing import trace
|
||||||
from synapse.metrics import LaterGauge
|
from synapse.metrics import LaterGauge
|
||||||
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
||||||
|
@ -1443,6 +1444,10 @@ class RoomMemberWorkerStore(EventsWorkerStore, CacheInvalidationWorkerStore):
|
||||||
is_encrypted=bool(row[9]),
|
is_encrypted=bool(row[9]),
|
||||||
)
|
)
|
||||||
for row in txn
|
for row in txn
|
||||||
|
# We filter out unknown room versions proactively. They
|
||||||
|
# shouldn't go down sync and their metadata may be in a broken
|
||||||
|
# state (causing errors).
|
||||||
|
if row[4] in KNOWN_ROOM_VERSIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
return await self.db_pool.runInteraction(
|
return await self.db_pool.runInteraction(
|
||||||
|
|
|
@ -1198,3 +1198,55 @@ class SlidingSyncRoomsMetaTestCase(SlidingSyncBase):
|
||||||
joined_dm_room_id: True,
|
joined_dm_room_id: True,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_old_room_with_unknown_room_version(self) -> None:
|
||||||
|
"""Test that an old room with unknown room version does not break
|
||||||
|
sync."""
|
||||||
|
user1_id = self.register_user("user1", "pass")
|
||||||
|
user1_tok = self.login(user1_id, "pass")
|
||||||
|
|
||||||
|
# We first create a standard room, then we'll change the room version in
|
||||||
|
# the DB.
|
||||||
|
room_id = self.helper.create_room_as(
|
||||||
|
user1_id,
|
||||||
|
tok=user1_tok,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Poke the database and update the room version to an unknown one.
|
||||||
|
self.get_success(
|
||||||
|
self.hs.get_datastores().main.db_pool.simple_update(
|
||||||
|
"rooms",
|
||||||
|
keyvalues={"room_id": room_id},
|
||||||
|
updatevalues={"room_version": "unknown-room-version"},
|
||||||
|
desc="updated-room-version",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Invalidate method so that it returns the currently updated version
|
||||||
|
# instead of the cached version.
|
||||||
|
self.hs.get_datastores().main.get_room_version_id.invalidate((room_id,))
|
||||||
|
|
||||||
|
# For old unknown room versions we won't have an entry in this table
|
||||||
|
# (due to us skipping unknown room versions in the background update).
|
||||||
|
self.get_success(
|
||||||
|
self.store.db_pool.simple_delete(
|
||||||
|
table="sliding_sync_joined_rooms",
|
||||||
|
keyvalues={"room_id": room_id},
|
||||||
|
desc="delete_sliding_room",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Also invalidate some caches to ensure we pull things from the DB.
|
||||||
|
self.store._events_stream_cache._entity_to_key.pop(room_id)
|
||||||
|
self.store._get_max_event_pos.invalidate((room_id,))
|
||||||
|
|
||||||
|
sync_body = {
|
||||||
|
"lists": {
|
||||||
|
"foo-list": {
|
||||||
|
"ranges": [[0, 1]],
|
||||||
|
"required_state": [],
|
||||||
|
"timeline_limit": 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response_body, _ = self.do_sync(sync_body, tok=user1_tok)
|
||||||
|
|
Loading…
Reference in New Issue