Add new columns tracking when we partial-joined (#13892)
This commit is contained in:
parent
87fe9db467
commit
f5aaa55e27
|
@ -0,0 +1 @@
|
||||||
|
Faster remote room joins: record _when_ we first partial-join to a room.
|
|
@ -581,7 +581,11 @@ class FederationHandler:
|
||||||
# Mark the room as having partial state.
|
# Mark the room as having partial state.
|
||||||
# The background process is responsible for unmarking this flag,
|
# The background process is responsible for unmarking this flag,
|
||||||
# even if the join fails.
|
# even if the join fails.
|
||||||
await self.store.store_partial_state_room(room_id, ret.servers_in_room)
|
await self.store.store_partial_state_room(
|
||||||
|
room_id=room_id,
|
||||||
|
servers=ret.servers_in_room,
|
||||||
|
device_lists_stream_id=self.store.get_device_stream_token(),
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
max_stream_id = (
|
max_stream_id = (
|
||||||
|
@ -606,6 +610,14 @@ class FederationHandler:
|
||||||
room_id,
|
room_id,
|
||||||
)
|
)
|
||||||
raise LimitExceededError(msg=e.msg, errcode=e.errcode, retry_after_ms=0)
|
raise LimitExceededError(msg=e.msg, errcode=e.errcode, retry_after_ms=0)
|
||||||
|
else:
|
||||||
|
# Record the join event id for future use (when we finish the full
|
||||||
|
# join). We have to do this after persisting the event to keep foreign
|
||||||
|
# key constraints intact.
|
||||||
|
if ret.partial_state:
|
||||||
|
await self.store.write_partial_state_rooms_join_event_id(
|
||||||
|
room_id, event.event_id
|
||||||
|
)
|
||||||
finally:
|
finally:
|
||||||
# Always kick off the background process that asynchronously fetches
|
# Always kick off the background process that asynchronously fetches
|
||||||
# state for the room.
|
# state for the room.
|
||||||
|
|
|
@ -1777,28 +1777,46 @@ class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore):
|
||||||
self,
|
self,
|
||||||
room_id: str,
|
room_id: str,
|
||||||
servers: Collection[str],
|
servers: Collection[str],
|
||||||
|
device_lists_stream_id: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Mark the given room as containing events with partial state
|
"""Mark the given room as containing events with partial state.
|
||||||
|
|
||||||
|
We also store additional data that describes _when_ we first partial-joined this
|
||||||
|
room, which helps us to keep other homeservers in sync when we finally fully
|
||||||
|
join this room.
|
||||||
|
|
||||||
|
We do not include a `join_event_id` here---we need to wait for the join event
|
||||||
|
to be persisted first.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
room_id: the ID of the room
|
room_id: the ID of the room
|
||||||
servers: other servers known to be in the room
|
servers: other servers known to be in the room
|
||||||
|
device_lists_stream_id: the device_lists stream ID at the time when we first
|
||||||
|
joined the room.
|
||||||
"""
|
"""
|
||||||
await self.db_pool.runInteraction(
|
await self.db_pool.runInteraction(
|
||||||
"store_partial_state_room",
|
"store_partial_state_room",
|
||||||
self._store_partial_state_room_txn,
|
self._store_partial_state_room_txn,
|
||||||
room_id,
|
room_id,
|
||||||
servers,
|
servers,
|
||||||
|
device_lists_stream_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _store_partial_state_room_txn(
|
def _store_partial_state_room_txn(
|
||||||
self, txn: LoggingTransaction, room_id: str, servers: Collection[str]
|
self,
|
||||||
|
txn: LoggingTransaction,
|
||||||
|
room_id: str,
|
||||||
|
servers: Collection[str],
|
||||||
|
device_lists_stream_id: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
DatabasePool.simple_insert_txn(
|
DatabasePool.simple_insert_txn(
|
||||||
txn,
|
txn,
|
||||||
table="partial_state_rooms",
|
table="partial_state_rooms",
|
||||||
values={
|
values={
|
||||||
"room_id": room_id,
|
"room_id": room_id,
|
||||||
|
"device_lists_stream_id": device_lists_stream_id,
|
||||||
|
# To be updated later once the join event is persisted.
|
||||||
|
"join_event_id": None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DatabasePool.simple_insert_many_txn(
|
DatabasePool.simple_insert_many_txn(
|
||||||
|
@ -1809,6 +1827,36 @@ class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore):
|
||||||
)
|
)
|
||||||
self._invalidate_cache_and_stream(txn, self.is_partial_state_room, (room_id,))
|
self._invalidate_cache_and_stream(txn, self.is_partial_state_room, (room_id,))
|
||||||
|
|
||||||
|
async def write_partial_state_rooms_join_event_id(
|
||||||
|
self,
|
||||||
|
room_id: str,
|
||||||
|
join_event_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Record the join event which resulted from a partial join.
|
||||||
|
|
||||||
|
We do this separately to `store_partial_state_room` because we need to wait for
|
||||||
|
the join event to be persisted. Otherwise we violate a foreign key constraint.
|
||||||
|
"""
|
||||||
|
await self.db_pool.runInteraction(
|
||||||
|
"write_partial_state_rooms_join_event_id",
|
||||||
|
self._write_partial_state_rooms_join_event_id,
|
||||||
|
room_id,
|
||||||
|
join_event_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _write_partial_state_rooms_join_event_id(
|
||||||
|
self,
|
||||||
|
txn: LoggingTransaction,
|
||||||
|
room_id: str,
|
||||||
|
join_event_id: str,
|
||||||
|
) -> None:
|
||||||
|
DatabasePool.simple_update_txn(
|
||||||
|
txn,
|
||||||
|
table="partial_state_rooms",
|
||||||
|
keyvalues={"room_id": room_id},
|
||||||
|
updatevalues={"join_event_id": join_event_id},
|
||||||
|
)
|
||||||
|
|
||||||
async def maybe_store_room_on_outlier_membership(
|
async def maybe_store_room_on_outlier_membership(
|
||||||
self, room_id: str, room_version: RoomVersion
|
self, room_id: str, room_version: RoomVersion
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* Copyright 2022 The Matrix.org Foundation C.I.C
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- To ensure we correctly notify other homeservers about device list changes from our
|
||||||
|
-- users after a partial join transitions to a full join, we need to know when we began
|
||||||
|
-- the partial join. For now it's sufficient to know the device_list stream_id at the
|
||||||
|
-- time of the partial join, and the join event created for us during a partial join.
|
||||||
|
--
|
||||||
|
-- Both columns are backwards compatible.
|
||||||
|
ALTER TABLE partial_state_rooms ADD COLUMN device_lists_stream_id BIGINT NOT NULL DEFAULT 0;
|
||||||
|
ALTER TABLE partial_state_rooms ADD COLUMN join_event_id TEXT REFERENCES events(event_id);
|
Loading…
Reference in New Issue