summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Morgan <andrew@amorgan.xyz>2021-11-29 18:32:05 +0000
committerAndrew Morgan <andrew@amorgan.xyz>2021-12-08 18:30:52 +0000
commitb80db21c19834ee9668a210e6f026501dd2eaae5 (patch)
treea1e3030b579305c87f0f1319484437c2c981c431
parentRefactor appservice interest-checking methods (diff)
downloadsynapse-b80db21c19834ee9668a210e6f026501dd2eaae5.tar.xz
Add some caching to interest methods
This also fixes (I believe) is_interested_in_presence, the cache of which was
never invalidated.

Note that namespaces can only be changed via a server restart. Users
leaving and joining rooms do change on the fly though.
-rw-r--r--synapse/appservice/__init__.py49
1 files changed, 37 insertions, 12 deletions
diff --git a/synapse/appservice/__init__.py b/synapse/appservice/__init__.py
index cf0e88fa22..f677fd6c4f 100644
--- a/synapse/appservice/__init__.py
+++ b/synapse/appservice/__init__.py
@@ -171,7 +171,28 @@ class ApplicationService:
                 return True
         return False
 
-    async def _is_interested_in_room(self, room_id: str, store: "DataStore") -> bool:
+    @cached(num_args=1, cache_context=True)
+    async def _is_interested_in_room(
+        self,
+        room_id: str,
+        store: "DataStore",
+        cache_context: _CacheContext,
+    ) -> bool:
+        """
+        Returns whether the application service is interested in a given room ID.
+
+        The appservice is considered to be interested in the room if either: the ID or one
+        of the aliases of the room is in the appservice's room ID or alias namespace
+        respectively, or if one of the members of the room fall into the appservice's user
+        namespace.
+
+        Args:
+            room_id: The ID of the room to check.
+            store: The homeserver's datastore class.
+
+        Returns:
+            True if the application service is interested in the room, False if not.
+        """
         # Check if we have interest in this room ID
         if self.is_room_id_in_namespace(room_id):
             return True
@@ -185,13 +206,16 @@ class ApplicationService:
         # And finally, perform an expensive check on whether the appservice
         # is interested in any users in the room based on their user ID
         # and the appservice's user namespace.
-        if await self.matches_user_in_member_list(room_id, store):
-            return True
-
-        return False
+        return await self.matches_user_in_member_list(
+            room_id, store, on_invalidate=cache_context.invalidate
+        )
 
+    @cached(num_args=1, cache_context=True)
     async def is_interested_in_event(
-        self, event: EventBase, store: Optional["DataStore"] = None
+        self,
+        event: EventBase,
+        cache_context: _CacheContext,
+        store: Optional["DataStore"] = None,
     ) -> bool:
         """Check if this service is interested in this event.
 
@@ -221,17 +245,16 @@ class ApplicationService:
         # TODO: The store is only optional here to aid testing this function. We should
         #  instead convert the tests to use HomeServerTestCase in order to get a working
         #  database instance.
-        if (
-            store is not None
-            and await self._is_interested_in_room(event.room_id, store)
+        if store is not None and await self._is_interested_in_room(
+            event.room_id, store, on_invalidate=cache_context.invalidate
         ):
             return True
 
         return False
 
-    @cached(num_args=1)
+    @cached(num_args=1, cache_context=True)
     async def is_interested_in_presence(
-        self, user_id: UserID, store: "DataStore"
+        self, user_id: UserID, store: "DataStore", cache_context: _CacheContext
     ) -> bool:
         """Check if this service is interested a user's presence
 
@@ -249,7 +272,9 @@ class ApplicationService:
 
         # Then find out if the appservice is interested in any of those rooms
         for room_id in room_ids:
-            if await self.matches_user_in_member_list(room_id, store):
+            if await self.matches_user_in_member_list(
+                room_id, store, on_invalidate=cache_context.invalidate
+            ):
                 return True
         return False