|
46 | 46 | # based on the current state when notifying workers over replication. |
47 | 47 | CURRENT_STATE_CACHE_NAME = "cs_cache_fake" |
48 | 48 |
|
| 49 | +# As above, but for invalidating event caches on history deletion |
| 50 | +PURGE_HISTORY_CACHE_NAME = "ph_cache_fake" |
| 51 | + |
| 52 | +# As above, but for invalidating room caches on room deletion |
| 53 | +DELETE_ROOM_CACHE_NAME = "dr_cache_fake" |
| 54 | + |
49 | 55 |
|
50 | 56 | class CacheInvalidationWorkerStore(SQLBaseStore): |
51 | 57 | def __init__( |
@@ -175,6 +181,23 @@ def process_replication_rows( |
175 | 181 | room_id = row.keys[0] |
176 | 182 | members_changed = set(row.keys[1:]) |
177 | 183 | self._invalidate_state_caches(room_id, members_changed) |
| 184 | + elif row.cache_func == PURGE_HISTORY_CACHE_NAME: |
| 185 | + if row.keys is None: |
| 186 | + raise Exception( |
| 187 | + "Can't send an 'invalidate all' for 'purge history' cache" |
| 188 | + ) |
| 189 | + |
| 190 | + room_id = row.keys[0] |
| 191 | + self._invalidate_caches_for_room_events(room_id) |
| 192 | + elif row.cache_func == DELETE_ROOM_CACHE_NAME: |
| 193 | + if row.keys is None: |
| 194 | + raise Exception( |
| 195 | + "Can't send an 'invalidate all' for 'delete room' cache" |
| 196 | + ) |
| 197 | + |
| 198 | + room_id = row.keys[0] |
| 199 | + self._invalidate_caches_for_room_events(room_id) |
| 200 | + self._invalidate_caches_for_room(room_id) |
178 | 201 | else: |
179 | 202 | self._attempt_to_invalidate_cache(row.cache_func, row.keys) |
180 | 203 |
|
@@ -226,6 +249,9 @@ def _invalidate_caches_for_event( |
226 | 249 | relates_to: Optional[str], |
227 | 250 | backfilled: bool, |
228 | 251 | ) -> None: |
| 252 | + # XXX: If you add something to this function make sure you add it to |
| 253 | + # `_invalidate_caches_for_room_events` as well. |
| 254 | + |
229 | 255 | # This invalidates any local in-memory cached event objects, the original |
230 | 256 | # process triggering the invalidation is responsible for clearing any external |
231 | 257 | # cached objects. |
@@ -271,6 +297,106 @@ def _invalidate_caches_for_event( |
271 | 297 | self._attempt_to_invalidate_cache("get_thread_participated", (relates_to,)) |
272 | 298 | self._attempt_to_invalidate_cache("get_threads", (room_id,)) |
273 | 299 |
|
| 300 | + def _invalidate_caches_for_room_events_and_stream( |
| 301 | + self, txn: LoggingTransaction, room_id: str |
| 302 | + ) -> None: |
| 303 | + """Invalidate caches associated with events in a room, and stream to |
| 304 | + replication. |
| 305 | +
|
| 306 | + Used when we delete events a room, but don't know which events we've |
| 307 | + deleted. |
| 308 | + """ |
| 309 | + |
| 310 | + self._send_invalidation_to_replication(txn, PURGE_HISTORY_CACHE_NAME, [room_id]) |
| 311 | + txn.call_after(self._invalidate_caches_for_room_events, room_id) |
| 312 | + |
| 313 | + def _invalidate_caches_for_room_events(self, room_id: str) -> None: |
| 314 | + """Invalidate caches associated with events in a room, and stream to |
| 315 | + replication. |
| 316 | +
|
| 317 | + Used when we delete events in a room, but don't know which events we've |
| 318 | + deleted. |
| 319 | + """ |
| 320 | + |
| 321 | + self._invalidate_local_get_event_cache_all() # type: ignore[attr-defined] |
| 322 | + |
| 323 | + self._attempt_to_invalidate_cache("have_seen_event", (room_id,)) |
| 324 | + self._attempt_to_invalidate_cache("get_latest_event_ids_in_room", (room_id,)) |
| 325 | + self._attempt_to_invalidate_cache( |
| 326 | + "get_unread_event_push_actions_by_room_for_user", (room_id,) |
| 327 | + ) |
| 328 | + |
| 329 | + self._attempt_to_invalidate_cache("_get_membership_from_event_id", None) |
| 330 | + self._attempt_to_invalidate_cache("get_relations_for_event", None) |
| 331 | + self._attempt_to_invalidate_cache("get_applicable_edit", None) |
| 332 | + self._attempt_to_invalidate_cache("get_thread_id", None) |
| 333 | + self._attempt_to_invalidate_cache("get_thread_id_for_receipts", None) |
| 334 | + self._attempt_to_invalidate_cache("get_invited_rooms_for_local_user", None) |
| 335 | + self._attempt_to_invalidate_cache( |
| 336 | + "get_rooms_for_user_with_stream_ordering", None |
| 337 | + ) |
| 338 | + self._attempt_to_invalidate_cache("get_rooms_for_user", None) |
| 339 | + self._attempt_to_invalidate_cache("get_references_for_event", None) |
| 340 | + self._attempt_to_invalidate_cache("get_thread_summary", None) |
| 341 | + self._attempt_to_invalidate_cache("get_thread_participated", None) |
| 342 | + self._attempt_to_invalidate_cache("get_threads", (room_id,)) |
| 343 | + |
| 344 | + self._attempt_to_invalidate_cache("_get_state_group_for_event", None) |
| 345 | + |
| 346 | + self._attempt_to_invalidate_cache("get_event_ordering", None) |
| 347 | + self._attempt_to_invalidate_cache("is_partial_state_event", None) |
| 348 | + self._attempt_to_invalidate_cache("_get_joined_profile_from_event_id", None) |
| 349 | + |
| 350 | + def _invalidate_caches_for_room_and_stream( |
| 351 | + self, txn: LoggingTransaction, room_id: str |
| 352 | + ) -> None: |
| 353 | + """Invalidate caches associated with rooms, and stream to replication. |
| 354 | +
|
| 355 | + Used when we delete rooms. |
| 356 | + """ |
| 357 | + |
| 358 | + self._send_invalidation_to_replication(txn, DELETE_ROOM_CACHE_NAME, [room_id]) |
| 359 | + txn.call_after(self._invalidate_caches_for_room, room_id) |
| 360 | + |
| 361 | + def _invalidate_caches_for_room(self, room_id: str) -> None: |
| 362 | + """Invalidate caches associated with rooms. |
| 363 | +
|
| 364 | + Used when we delete rooms. |
| 365 | + """ |
| 366 | + |
| 367 | + # If we've deleted the room then we also need to purge all event caches. |
| 368 | + self._invalidate_caches_for_room_events(room_id) |
| 369 | + |
| 370 | + self._attempt_to_invalidate_cache("get_account_data_for_room", None) |
| 371 | + self._attempt_to_invalidate_cache("get_account_data_for_room_and_type", None) |
| 372 | + self._attempt_to_invalidate_cache("get_aliases_for_room", (room_id,)) |
| 373 | + self._attempt_to_invalidate_cache("get_latest_event_ids_in_room", (room_id,)) |
| 374 | + self._attempt_to_invalidate_cache("_get_forward_extremeties_for_room", None) |
| 375 | + self._attempt_to_invalidate_cache( |
| 376 | + "get_unread_event_push_actions_by_room_for_user", (room_id,) |
| 377 | + ) |
| 378 | + self._attempt_to_invalidate_cache( |
| 379 | + "_get_linearized_receipts_for_room", (room_id,) |
| 380 | + ) |
| 381 | + self._attempt_to_invalidate_cache("is_room_blocked", (room_id,)) |
| 382 | + self._attempt_to_invalidate_cache("get_retention_policy_for_room", (room_id,)) |
| 383 | + self._attempt_to_invalidate_cache( |
| 384 | + "_get_partial_state_servers_at_join", (room_id,) |
| 385 | + ) |
| 386 | + self._attempt_to_invalidate_cache("is_partial_state_room", (room_id,)) |
| 387 | + self._attempt_to_invalidate_cache("get_invited_rooms_for_local_user", None) |
| 388 | + self._attempt_to_invalidate_cache( |
| 389 | + "get_current_hosts_in_room_ordered", (room_id,) |
| 390 | + ) |
| 391 | + self._attempt_to_invalidate_cache("did_forget", None) |
| 392 | + self._attempt_to_invalidate_cache("get_forgotten_rooms_for_user", None) |
| 393 | + self._attempt_to_invalidate_cache("_get_membership_from_event_id", None) |
| 394 | + self._attempt_to_invalidate_cache("get_room_version_id", (room_id,)) |
| 395 | + |
| 396 | + # And delete state caches. |
| 397 | + |
| 398 | + self._invalidate_state_caches_all(room_id) |
| 399 | + |
274 | 400 | async def invalidate_cache_and_stream( |
275 | 401 | self, cache_name: str, keys: Tuple[Any, ...] |
276 | 402 | ) -> None: |
@@ -377,6 +503,14 @@ def _send_invalidation_to_replication( |
377 | 503 | "Can't stream invalidate all with magic current state cache" |
378 | 504 | ) |
379 | 505 |
|
| 506 | + if cache_name == PURGE_HISTORY_CACHE_NAME and keys is None: |
| 507 | + raise Exception( |
| 508 | + "Can't stream invalidate all with magic purge history cache" |
| 509 | + ) |
| 510 | + |
| 511 | + if cache_name == DELETE_ROOM_CACHE_NAME and keys is None: |
| 512 | + raise Exception("Can't stream invalidate all with magic delete room cache") |
| 513 | + |
380 | 514 | if isinstance(self.database_engine, PostgresEngine): |
381 | 515 | assert self._cache_id_gen is not None |
382 | 516 |
|
|
0 commit comments