Request partial joins by default (#14905)

* Request partial joins by default

This is a little sloppy, but we are trying to gain confidence in faster
joins in the upcoming RC.

Admins can still opt out by adding the following to their Synapse
config:

```yaml
experimental:
    faster_joins: false
```

We may revert this change before the release proper, depending on how
testing in the wild goes.

* Changelog

* Try to fix the backfill test failures

* Upgrade notes

* Postgres compat?
This commit is contained in:
David Robertson 2023-01-24 15:28:20 +00:00 committed by GitHub
parent 80d44060c9
commit 4607be0b7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 7 deletions

View File

@ -0,0 +1 @@
Faster joins: request partial joins by default. Admins can opt-out of this for the time being---see the upgrade notes.

View File

@ -90,6 +90,19 @@ process, for example:
# Upgrading to v1.76.0 # Upgrading to v1.76.0
## Faster joins are enabled by default
When joining a room for the first time, Synapse 1.76.0rc1 will request a partial join from the other server by default. Previously, server admins had to opt-in to this using an experimental config flag.
Server admins can opt out of this feature for the time being by setting
```yaml
experimental:
faster_joins: false
```
in their server config.
## Changes to the account data replication streams ## Changes to the account data replication streams
Synapse has changed the format of the account data and devices replication Synapse has changed the format of the account data and devices replication

View File

@ -84,7 +84,7 @@ class ExperimentalConfig(Config):
# experimental support for faster joins over federation # experimental support for faster joins over federation
# (MSC2775, MSC3706, MSC3895) # (MSC2775, MSC3706, MSC3895)
# requires a target server that can provide a partial join response (MSC3706) # requires a target server that can provide a partial join response (MSC3706)
self.faster_joins_enabled: bool = experimental.get("faster_joins", False) self.faster_joins_enabled: bool = experimental.get("faster_joins", True)
# MSC3720 (Account status endpoint) # MSC3720 (Account status endpoint)
self.msc3720_enabled: bool = experimental.get("msc3720_enabled", False) self.msc3720_enabled: bool = experimental.get("msc3720_enabled", False)

View File

@ -67,7 +67,7 @@ from synapse.storage.database import (
make_in_list_sql_clause, make_in_list_sql_clause,
) )
from synapse.storage.databases.main.events_worker import EventsWorkerStore from synapse.storage.databases.main.events_worker import EventsWorkerStore
from synapse.storage.engines import BaseDatabaseEngine, PostgresEngine from synapse.storage.engines import BaseDatabaseEngine, PostgresEngine, Sqlite3Engine
from synapse.storage.util.id_generators import MultiWriterIdGenerator from synapse.storage.util.id_generators import MultiWriterIdGenerator
from synapse.types import PersistedEventPosition, RoomStreamToken from synapse.types import PersistedEventPosition, RoomStreamToken
from synapse.util.caches.descriptors import cached from synapse.util.caches.descriptors import cached
@ -944,12 +944,40 @@ class StreamWorkerStore(EventsWorkerStore, SQLBaseStore):
room_id room_id
stream_key stream_key
""" """
sql = ( if isinstance(self.database_engine, PostgresEngine):
"SELECT coalesce(MIN(topological_ordering), 0) FROM events" min_function = "LEAST"
" WHERE room_id = ? AND stream_ordering >= ?" elif isinstance(self.database_engine, Sqlite3Engine):
) min_function = "MIN"
else:
raise RuntimeError(f"Unknown database engine {self.database_engine}")
# This query used to be
# SELECT COALESCE(MIN(topological_ordering), 0) FROM events
# WHERE room_id = ? and events.stream_ordering >= {stream_key}
# which returns 0 if the stream_key is newer than any event in
# the room. That's not wrong, but it seems to interact oddly with backfill,
# requiring a second call to /messages to actually backfill from a remote
# homeserver.
#
# Instead, rollback the stream ordering to that after the most recent event in
# this room.
sql = f"""
WITH fallback(max_stream_ordering) AS (
SELECT MAX(stream_ordering)
FROM events
WHERE room_id = ?
)
SELECT COALESCE(MIN(topological_ordering), 0) FROM events
WHERE
room_id = ?
AND events.stream_ordering >= {min_function}(
?,
(SELECT max_stream_ordering FROM fallback)
)
"""
row = await self.db_pool.execute( row = await self.db_pool.execute(
"get_current_topological_token", None, sql, room_id, stream_key "get_current_topological_token", None, sql, room_id, room_id, stream_key
) )
return row[0][0] if row else 0 return row[0][0] if row else 0