Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Request partial joins by default (#14905)
Browse files Browse the repository at this point in the history
* 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?
  • Loading branch information
David Robertson authored Jan 24, 2023
1 parent 80d4406 commit 4607be0
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog.d/14905.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Faster joins: request partial joins by default. Admins can opt-out of this for the time being---see the upgrade notes.
13 changes: 13 additions & 0 deletions docs/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ process, for example:
# 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
Synapse has changed the format of the account data and devices replication
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
# experimental support for faster joins over federation
# (MSC2775, MSC3706, MSC3895)
# 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)
self.msc3720_enabled: bool = experimental.get("msc3720_enabled", False)
Expand Down
40 changes: 34 additions & 6 deletions synapse/storage/databases/main/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
make_in_list_sql_clause,
)
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.types import PersistedEventPosition, RoomStreamToken
from synapse.util.caches.descriptors import cached
Expand Down Expand Up @@ -944,12 +944,40 @@ async def get_current_topological_token(self, room_id: str, stream_key: int) ->
room_id
stream_key
"""
sql = (
"SELECT coalesce(MIN(topological_ordering), 0) FROM events"
" WHERE room_id = ? AND stream_ordering >= ?"
)
if isinstance(self.database_engine, PostgresEngine):
min_function = "LEAST"
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(
"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

Expand Down

0 comments on commit 4607be0

Please sign in to comment.