Add a background update to clear tombstoned rooms from the directory (#6648)
* Add a background update to clear tombstoned rooms from the directory * use the ABC metaclass
This commit is contained in:
parent
9824a39d80
commit
85db7f73be
|
@ -0,0 +1 @@
|
|||
Ensure that upgraded rooms are removed from the directory.
|
|
@ -166,6 +166,11 @@ class Store(
|
|||
logger.exception("Failed to insert: %s", table)
|
||||
raise
|
||||
|
||||
def set_room_is_public(self, room_id, is_public):
|
||||
raise Exception(
|
||||
"Attempt to set room_is_public during port_db: database not empty?"
|
||||
)
|
||||
|
||||
|
||||
class MockHomeserver:
|
||||
def __init__(self, config):
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# limitations under the License.
|
||||
import logging
|
||||
import random
|
||||
from abc import ABCMeta
|
||||
|
||||
from six import PY2
|
||||
from six.moves import builtins
|
||||
|
@ -30,7 +31,8 @@ from synapse.types import get_domain_from_id
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SQLBaseStore(object):
|
||||
# some of our subclasses have abstract methods, so we use the ABCMeta metaclass.
|
||||
class SQLBaseStore(metaclass=ABCMeta):
|
||||
"""Base class for data stores that holds helper functions.
|
||||
|
||||
Note that multiple instances of this class will exist as there will be one
|
||||
|
|
|
@ -436,6 +436,21 @@ class BackgroundUpdater(object):
|
|||
"background_updates", keyvalues={"update_name": update_name}
|
||||
)
|
||||
|
||||
def _background_update_progress(self, update_name: str, progress: dict):
|
||||
"""Update the progress of a background update
|
||||
|
||||
Args:
|
||||
update_name: The name of the background update task
|
||||
progress: The progress of the update.
|
||||
"""
|
||||
|
||||
return self.db.runInteraction(
|
||||
"background_update_progress",
|
||||
self._background_update_progress_txn,
|
||||
update_name,
|
||||
progress,
|
||||
)
|
||||
|
||||
def _background_update_progress_txn(self, txn, update_name, progress):
|
||||
"""Update the progress of a background update
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import collections
|
||||
import logging
|
||||
import re
|
||||
from abc import abstractmethod
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from six import integer_types
|
||||
|
@ -367,6 +368,8 @@ class RoomWorkerStore(SQLBaseStore):
|
|||
|
||||
|
||||
class RoomBackgroundUpdateStore(SQLBaseStore):
|
||||
REMOVE_TOMESTONED_ROOMS_BG_UPDATE = "remove_tombstoned_rooms_from_directory"
|
||||
|
||||
def __init__(self, database: Database, db_conn, hs):
|
||||
super(RoomBackgroundUpdateStore, self).__init__(database, db_conn, hs)
|
||||
|
||||
|
@ -376,6 +379,11 @@ class RoomBackgroundUpdateStore(SQLBaseStore):
|
|||
"insert_room_retention", self._background_insert_retention,
|
||||
)
|
||||
|
||||
self.db.updates.register_background_update_handler(
|
||||
self.REMOVE_TOMESTONED_ROOMS_BG_UPDATE,
|
||||
self._remove_tombstoned_rooms_from_directory,
|
||||
)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _background_insert_retention(self, progress, batch_size):
|
||||
"""Retrieves a list of all rooms within a range and inserts an entry for each of
|
||||
|
@ -444,6 +452,62 @@ class RoomBackgroundUpdateStore(SQLBaseStore):
|
|||
|
||||
defer.returnValue(batch_size)
|
||||
|
||||
async def _remove_tombstoned_rooms_from_directory(
|
||||
self, progress, batch_size
|
||||
) -> int:
|
||||
"""Removes any rooms with tombstone events from the room directory
|
||||
|
||||
Nowadays this is handled by the room upgrade handler, but we may have some
|
||||
that got left behind
|
||||
"""
|
||||
|
||||
last_room = progress.get("room_id", "")
|
||||
|
||||
def _get_rooms(txn):
|
||||
txn.execute(
|
||||
"""
|
||||
SELECT room_id
|
||||
FROM rooms r
|
||||
INNER JOIN current_state_events cse USING (room_id)
|
||||
WHERE room_id > ? AND r.is_public
|
||||
AND cse.type = '%s' AND cse.state_key = ''
|
||||
ORDER BY room_id ASC
|
||||
LIMIT ?;
|
||||
"""
|
||||
% EventTypes.Tombstone,
|
||||
(last_room, batch_size),
|
||||
)
|
||||
|
||||
return [row[0] for row in txn]
|
||||
|
||||
rooms = await self.db.runInteraction(
|
||||
"get_tombstoned_directory_rooms", _get_rooms
|
||||
)
|
||||
|
||||
if not rooms:
|
||||
await self.db.updates._end_background_update(
|
||||
self.REMOVE_TOMESTONED_ROOMS_BG_UPDATE
|
||||
)
|
||||
return 0
|
||||
|
||||
for room_id in rooms:
|
||||
logger.info("Removing tombstoned room %s from the directory", room_id)
|
||||
await self.set_room_is_public(room_id, False)
|
||||
|
||||
await self.db.updates._background_update_progress(
|
||||
self.REMOVE_TOMESTONED_ROOMS_BG_UPDATE, {"room_id": rooms[-1]}
|
||||
)
|
||||
|
||||
return len(rooms)
|
||||
|
||||
@abstractmethod
|
||||
def set_room_is_public(self, room_id, is_public):
|
||||
# this will need to be implemented if a background update is performed with
|
||||
# existing (tombstoned, public) rooms in the database.
|
||||
#
|
||||
# It's overridden by RoomStore for the synapse master.
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore, SearchStore):
|
||||
def __init__(self, database: Database, db_conn, hs):
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
-- Now that #6232 is a thing, we can remove old rooms from the directory.
|
||||
INSERT INTO background_updates (update_name, progress_json) VALUES
|
||||
('remove_tombstoned_rooms_from_directory', '{}');
|
Loading…
Reference in New Issue