Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sliding Sync: Speed up background updates to populate Sliding Sync tables #17676

Open
wants to merge 26 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
944661a
Pull from `room_stats_state`
MadLittleMods Sep 6, 2024
5894fc2
`concurrently_execute` data fetching
MadLittleMods Sep 6, 2024
b4fcbc9
`concurrently_execute` inserting
MadLittleMods Sep 6, 2024
ce7e1b4
Look for previous snapshot
MadLittleMods Sep 6, 2024
27caa47
Work on snapshots background update
MadLittleMods Sep 6, 2024
333b472
TODO and asserts
MadLittleMods Sep 6, 2024
ef2f553
Merge branch 'develop' into madlittlemods/sliding-sync-faster-backgro…
MadLittleMods Sep 9, 2024
f74106b
Implement `insertion_value_names`/`insertion_value_values` for `simpl…
MadLittleMods Sep 9, 2024
836bcae
Fix nothing being upserted
MadLittleMods Sep 10, 2024
90371d4
Sort by `event_stream_ordering` so we can re-use snapshots along the way
MadLittleMods Sep 10, 2024
2c2146d
Only re-use for join memberships
MadLittleMods Sep 10, 2024
1078163
Make sure re-use doesn't blow up
MadLittleMods Sep 10, 2024
a4cc5eb
Get snapshots info concurrently
MadLittleMods Sep 10, 2024
815ef2f
Read from the `room_stats_state` table
MadLittleMods Sep 10, 2024
1688212
Uncomment and remove todo
MadLittleMods Sep 10, 2024
f045574
Better comments
MadLittleMods Sep 10, 2024
a2da537
Add changelog
MadLittleMods Sep 10, 2024
ca4afad
Be more precise
MadLittleMods Sep 10, 2024
e2dca5d
Merge branch 'develop' into madlittlemods/sliding-sync-faster-backgro…
MadLittleMods Sep 10, 2024
bb5784b
Need to sort by room_id to make progress
MadLittleMods Sep 10, 2024
6f3e8be
Add assertion message to better debug
MadLittleMods Sep 10, 2024
8477df4
Fix f-string
MadLittleMods Sep 10, 2024
76cc662
Use `events.stream_ordering` since `local_current_membership.event_st…
MadLittleMods Sep 10, 2024
2e8f5d6
Use correct table
MadLittleMods Sep 10, 2024
6565380
Rely on `events.stream_ordering`
MadLittleMods Sep 11, 2024
e5f133d
Merge branch 'develop' into madlittlemods/sliding-sync-faster-backgro…
MadLittleMods Sep 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/17676.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pre-populate room data used in experimental [MSC3575](https://github.com/matrix-org/matrix-spec-proposals/pull/3575) Sliding Sync `/sync` endpoint for quick filtering/sorting.
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
67 changes: 61 additions & 6 deletions synapse/storage/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,11 @@ async def simple_upsert_many(
key_values: Collection[Collection[Any]],
value_names: Collection[str],
value_values: Collection[Collection[Any]],
# Given these are the same type as the normal values, force keyword-only so that
# they can't be confused.
*,
insertion_value_names: Collection[str] = [],
insertion_value_values: Collection[Iterable[Any]] = [],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding support for insertion only values on upsert.

Same as we already have for simple_upsert(insertion_values={})

desc: str,
) -> None:
"""
Expand All @@ -1497,6 +1502,8 @@ async def simple_upsert_many(
key_values,
value_names,
value_values,
insertion_value_names=insertion_value_names,
insertion_value_values=insertion_value_values,
db_autocommit=autocommit,
)

Expand All @@ -1508,6 +1515,11 @@ def simple_upsert_many_txn(
key_values: Collection[Iterable[Any]],
value_names: Collection[str],
value_values: Collection[Iterable[Any]],
# Given these are the same type as the normal values, force keyword-only so that
# they can't be confused.
*,
insertion_value_names: Collection[str] = [],
insertion_value_values: Collection[Iterable[Any]] = [],
) -> None:
"""
Upsert, many times.
Expand All @@ -1519,6 +1531,9 @@ def simple_upsert_many_txn(
value_names: The value column names
value_values: A list of each row's value column values.
Ignored if value_names is empty.
insertion_value_names: The value column names to use only when inserting
insertion_value_values: A list of each row's value column values to use only
when inserting. Ignored if `insertion_value_names` is empty.
"""
# If there's nothing to upsert, then skip executing the query.
if not key_values:
Expand All @@ -1528,14 +1543,30 @@ def simple_upsert_many_txn(
# zip() works correctly.
if not value_names:
value_values = [() for x in range(len(key_values))]
elif len(value_values) != len(key_values):
elif len(key_values) != len(value_values):
raise ValueError(
f"{len(key_values)} key rows and {len(value_values)} value rows: should be the same number."
)

# No value columns, therefore make a blank list so that the following
# zip() works correctly.
if not insertion_value_names:
insertion_value_values = [() for x in range(len(key_values))]
elif len(key_values) != len(insertion_value_values):
raise ValueError(
f"{len(key_values)} key rows and {len(insertion_value_values)} insertion value rows: should be the same number."
)

if table not in self._unsafe_to_upsert_tables:
return self.simple_upsert_many_txn_native_upsert(
txn, table, key_names, key_values, value_names, value_values
txn,
table,
key_names,
key_values,
value_names,
value_values,
insertion_value_names=insertion_value_names,
insertion_value_values=insertion_value_values,
)
else:
return self.simple_upsert_many_txn_emulated(
Expand All @@ -1545,6 +1576,8 @@ def simple_upsert_many_txn(
key_values,
value_names,
value_values,
insertion_value_names=insertion_value_names,
insertion_value_values=insertion_value_values,
)

def simple_upsert_many_txn_emulated(
Expand All @@ -1555,6 +1588,11 @@ def simple_upsert_many_txn_emulated(
key_values: Collection[Iterable[Any]],
value_names: Collection[str],
value_values: Iterable[Iterable[Any]],
# Given these are the same type as the normal values, force keyword-only so that
# they can't be confused.
*,
insertion_value_names: Collection[str] = [],
insertion_value_values: Collection[Iterable[Any]] = [],
) -> None:
"""
Upsert, many times, but without native UPSERT support or batching.
Expand All @@ -1566,18 +1604,26 @@ def simple_upsert_many_txn_emulated(
value_names: The value column names
value_values: A list of each row's value column values.
Ignored if value_names is empty.
insertion_value_names: The value column names to use only when inserting
insertion_value_values: A list of each row's value column values to use only
when inserting. Ignored if `insertion_value_names` is empty.
"""

# Lock the table just once, to prevent it being done once per row.
# Note that, according to Postgres' documentation, once obtained,
# the lock is held for the remainder of the current transaction.
self.engine.lock_table(txn, table)

for keyv, valv in zip(key_values, value_values):
for keyv, valv, insertionv in zip(
key_values, value_values, insertion_value_values
):
_keys = dict(zip(key_names, keyv))
_vals = dict(zip(value_names, valv))
_insertion_vals = dict(zip(insertion_value_names, insertionv))

self.simple_upsert_txn_emulated(txn, table, _keys, _vals, lock=False)
self.simple_upsert_txn_emulated(
txn, table, _keys, _vals, insertion_values=_insertion_vals, lock=False
)

@staticmethod
def simple_upsert_many_txn_native_upsert(
Expand All @@ -1587,6 +1633,11 @@ def simple_upsert_many_txn_native_upsert(
key_values: Collection[Iterable[Any]],
value_names: Collection[str],
value_values: Iterable[Iterable[Any]],
# Given these are the same type as the normal values, force keyword-only so that
# they can't be confused.
*,
insertion_value_names: Collection[str] = [],
insertion_value_values: Collection[Iterable[Any]] = [],
) -> None:
"""
Upsert, many times, using batching where possible.
Expand All @@ -1598,10 +1649,14 @@ def simple_upsert_many_txn_native_upsert(
value_names: The value column names
value_values: A list of each row's value column values.
Ignored if value_names is empty.
insertion_value_names: The value column names to use only when inserting
insertion_value_values: A list of each row's value column values to use only
when inserting. Ignored if `insertion_value_names` is empty.
"""
allnames: List[str] = []
allnames.extend(key_names)
allnames.extend(value_names)
allnames.extend(insertion_value_names)

if not value_names:
latter = "NOTHING"
Expand All @@ -1612,8 +1667,8 @@ def simple_upsert_many_txn_native_upsert(

args = []

for x, y in zip(key_values, value_values):
args.append(tuple(x) + tuple(y))
for x, y, z in zip(key_values, value_values, insertion_value_values):
args.append(tuple(x) + tuple(y) + tuple(z))

if isinstance(txn.database_engine, PostgresEngine):
# We use `execute_values` as it can be a lot faster than `execute_batch`,
Expand Down
4 changes: 2 additions & 2 deletions synapse/storage/databases/main/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class SlidingSyncStateInsertValues(TypedDict, total=False):
"""

room_type: Optional[str]
is_encrypted: Optional[bool]
is_encrypted: bool
room_name: Optional[str]
tombstone_successor_room_id: Optional[str]

Expand All @@ -150,7 +150,7 @@ class SlidingSyncMembershipSnapshotSharedInsertValues(
multiple memberships
"""

has_known_state: Optional[bool]
has_known_state: bool


@attr.s(slots=True, auto_attribs=True)
Expand Down
Loading
Loading