summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2018-06-25 19:49:13 +0100
committerErik Johnston <erik@matrix.org>2018-06-25 19:49:13 +0100
commitea7a9c0483d547014404d3266446bb1b26c1076a (patch)
treebafd0844fb909744767b879653e940cba4f2ad6e /synapse
parenttypos (diff)
downloadsynapse-ea7a9c0483d547014404d3266446bb1b26c1076a.tar.xz
Add fast path to _filter_events_for_server
Most rooms have a trivial history visibility like "shared" or
"world_readable", especially large rooms, so lets not bother getting the
full membership of those rooms in that case.
Diffstat (limited to 'synapse')
-rw-r--r--synapse/handlers/federation.py35
1 files changed, 34 insertions, 1 deletions
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index 1ca56c2c97..123cdb5fab 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -460,11 +460,44 @@ class FederationHandler(BaseHandler):
     @measure_func("_filter_events_for_server")
     @defer.inlineCallbacks
     def _filter_events_for_server(self, server_name, room_id, events):
+        # First lets check to see if all the events have a history visibility
+        # of "shared" or "world_readable". If thats the case then we don't
+        # need to check membership (as we know the server is in the room).
         event_to_state_ids = yield self.store.get_state_ids_for_events(
             frozenset(e.event_id for e in events),
             types=(
                 (EventTypes.RoomHistoryVisibility, ""),
-                (EventTypes.Member, None),
+            )
+        )
+
+        visibility_ids = set()
+        for sids in event_to_state_ids.itervalues():
+            hist = event_to_state_ids.get((EventTypes.RoomHistoryVisibility, ""))
+            if hist:
+                visibility_ids.add(hist)
+
+        # If we failed to find any history visibility events then the default
+        # is "shared" visiblity.
+        if not visibility_ids:
+            defer.returnValue(events)
+
+        events = yield self.store.get_events(visibility_ids)
+        all_open = all(
+            e.content.get("history_visibility") in (None, "shared", "world_readable")
+            for e in events
+        )
+
+        if all_open:
+            defer.returnValue(events)
+
+        # Ok, so we're dealing with events that have non-trivial visibility
+        # rules, so we need to also get the memberships of the room.
+
+        event_to_state_ids = yield self.store.get_state_ids_for_events(
+            frozenset(e.event_id for e in events),
+            types=(
+                (EventTypes.RoomHistoryVisibility, ""),
+                (EventTypes.Member, None)
             )
         )