Skip to content

Commit dab88a7

Browse files
Sliding Sync: Make PerConnectionState immutable (#17600)
This is so that we can cache it. We also move the sliding sync types to `synapse/types/handlers/sliding_sync.py`. This is mainly in-prep for The only change in behaviour is that `RoomSyncConfig.combine_sync_config(..)` now returns a new room sync config rather than mutating in-place. Reviewable commit-by-commit. --------- Co-authored-by: Eric Eastwood <[email protected]>
1 parent 8678516 commit dab88a7

File tree

9 files changed

+443
-444
lines changed

9 files changed

+443
-444
lines changed

changelog.d/17600.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make the sliding sync `PerConnectionState` class immutable.

scripts-dev/mypy_synapse_plugin.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
NoneType,
3939
TupleType,
4040
TypeAliasType,
41+
TypeVarType,
4142
UninhabitedType,
4243
UnionType,
4344
)
@@ -233,6 +234,7 @@ def check_is_cacheable(
233234
"synapse.synapse_rust.push.FilteredPushRules",
234235
# This is technically not immutable, but close enough.
235236
"signedjson.types.VerifyKey",
237+
"synapse.types.StrCollection",
236238
}
237239

238240
# Immutable containers only if the values are also immutable.
@@ -298,7 +300,7 @@ def is_cacheable(
298300

299301
elif rt.type.fullname in MUTABLE_CONTAINER_TYPES:
300302
# Mutable containers are mutable regardless of their underlying type.
301-
return False, None
303+
return False, f"container {rt.type.fullname} is mutable"
302304

303305
elif "attrs" in rt.type.metadata:
304306
# attrs classes are only cachable iff it is frozen (immutable itself)
@@ -318,6 +320,9 @@ def is_cacheable(
318320
else:
319321
return False, "non-frozen attrs class"
320322

323+
elif rt.type.is_enum:
324+
# We assume Enum values are immutable
325+
return True, None
321326
else:
322327
# Ensure we fail for unknown types, these generally means that the
323328
# above code is not complete.
@@ -326,6 +331,18 @@ def is_cacheable(
326331
f"Don't know how to handle {rt.type.fullname} return type instance",
327332
)
328333

334+
elif isinstance(rt, TypeVarType):
335+
# We consider TypeVars immutable if they are bound to a set of immutable
336+
# types.
337+
if rt.values:
338+
for value in rt.values:
339+
ok, note = is_cacheable(value, signature, verbose)
340+
if not ok:
341+
return False, f"TypeVar bound not cacheable {value}"
342+
return True, None
343+
344+
return False, "TypeVar is unbound"
345+
329346
elif isinstance(rt, NoneType):
330347
# None is cachable.
331348
return True, None

synapse/handlers/sliding_sync/__init__.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@
2929
_RoomMembershipForUser,
3030
)
3131
from synapse.handlers.sliding_sync.store import SlidingSyncConnectionStore
32-
from synapse.handlers.sliding_sync.types import (
33-
HaveSentRoomFlag,
34-
MutablePerConnectionState,
35-
PerConnectionState,
36-
RoomSyncConfig,
37-
StateValues,
38-
)
3932
from synapse.logging.opentracing import (
4033
SynapseTags,
4134
log_kv,
@@ -57,7 +50,15 @@
5750
StreamKeyType,
5851
StreamToken,
5952
)
60-
from synapse.types.handlers import SlidingSyncConfig, SlidingSyncResult
53+
from synapse.types.handlers.sliding_sync import (
54+
HaveSentRoomFlag,
55+
MutablePerConnectionState,
56+
PerConnectionState,
57+
RoomSyncConfig,
58+
SlidingSyncConfig,
59+
SlidingSyncResult,
60+
StateValues,
61+
)
6162
from synapse.types.state import StateFilter
6263
from synapse.util.async_helpers import concurrently_execute
6364
from synapse.visibility import filter_events_for_client

synapse/handlers/sliding_sync/extensions.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020

2121
from synapse.api.constants import AccountDataTypes, EduTypes
2222
from synapse.handlers.receipts import ReceiptEventSource
23-
from synapse.handlers.sliding_sync.types import (
24-
HaveSentRoomFlag,
25-
MutablePerConnectionState,
26-
PerConnectionState,
27-
)
2823
from synapse.logging.opentracing import trace
2924
from synapse.storage.databases.main.receipts import ReceiptInRoom
3025
from synapse.types import (
@@ -35,7 +30,14 @@
3530
StrCollection,
3631
StreamToken,
3732
)
38-
from synapse.types.handlers import OperationType, SlidingSyncConfig, SlidingSyncResult
33+
from synapse.types.handlers.sliding_sync import (
34+
HaveSentRoomFlag,
35+
MutablePerConnectionState,
36+
OperationType,
37+
PerConnectionState,
38+
SlidingSyncConfig,
39+
SlidingSyncResult,
40+
)
3941

4042
if TYPE_CHECKING:
4143
from synapse.server import HomeServer

synapse/handlers/sliding_sync/room_lists.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@
4040
)
4141
from synapse.events import StrippedStateEvent
4242
from synapse.events.utils import parse_stripped_state_event
43-
from synapse.handlers.sliding_sync.types import (
44-
HaveSentRoomFlag,
45-
PerConnectionState,
46-
RoomSyncConfig,
47-
)
4843
from synapse.logging.opentracing import start_active_span, trace
4944
from synapse.storage.databases.main.state import (
5045
ROOM_UNKNOWN_SENTINEL,
@@ -61,7 +56,14 @@
6156
StreamToken,
6257
UserID,
6358
)
64-
from synapse.types.handlers import OperationType, SlidingSyncConfig, SlidingSyncResult
59+
from synapse.types.handlers.sliding_sync import (
60+
HaveSentRoomFlag,
61+
OperationType,
62+
PerConnectionState,
63+
RoomSyncConfig,
64+
SlidingSyncConfig,
65+
SlidingSyncResult,
66+
)
6567
from synapse.types.state import StateFilter
6668

6769
if TYPE_CHECKING:
@@ -279,15 +281,11 @@ async def compute_interested_rooms(
279281
room_id
280282
)
281283
if existing_room_sync_config is not None:
282-
existing_room_sync_config.combine_room_sync_config(
284+
room_sync_config = existing_room_sync_config.combine_room_sync_config(
283285
room_sync_config
284286
)
285-
else:
286-
# Make a copy so if we modify it later, it doesn't
287-
# affect all references.
288-
relevant_room_map[room_id] = (
289-
room_sync_config.deep_copy()
290-
)
287+
288+
relevant_room_map[room_id] = room_sync_config
291289

292290
room_ids_in_list.append(room_id)
293291

@@ -351,11 +349,13 @@ async def compute_interested_rooms(
351349
# and need to fetch more info about.
352350
existing_room_sync_config = relevant_room_map.get(room_id)
353351
if existing_room_sync_config is not None:
354-
existing_room_sync_config.combine_room_sync_config(
355-
room_sync_config
352+
room_sync_config = (
353+
existing_room_sync_config.combine_room_sync_config(
354+
room_sync_config
355+
)
356356
)
357-
else:
358-
relevant_room_map[room_id] = room_sync_config
357+
358+
relevant_room_map[room_id] = room_sync_config
359359

360360
# Filtered subset of `relevant_room_map` for rooms that may have updates
361361
# (in the event stream)

synapse/handlers/sliding_sync/store.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
import attr
1919

2020
from synapse.api.errors import SlidingSyncUnknownPosition
21-
from synapse.handlers.sliding_sync.types import (
21+
from synapse.logging.opentracing import trace
22+
from synapse.types import SlidingSyncStreamToken
23+
from synapse.types.handlers.sliding_sync import (
2224
MutablePerConnectionState,
2325
PerConnectionState,
26+
SlidingSyncConfig,
2427
)
25-
from synapse.logging.opentracing import trace
26-
from synapse.types import SlidingSyncStreamToken
27-
from synapse.types.handlers import SlidingSyncConfig
2828

2929
if TYPE_CHECKING:
3030
pass

0 commit comments

Comments
 (0)