summary refs log tree commit diff
path: root/synapse/handlers
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2016-01-19 11:27:27 +0000
committerErik Johnston <erik@matrix.org>2016-01-19 11:27:27 +0000
commit47e7963e50704a1a981b8c009f8403085be721a6 (patch)
tree1a8b4930d67c314c21d40e8e48436a0b246476f1 /synapse/handlers
parentMerge pull request #503 from matrix-org/daniel/nonghosts (diff)
parentTake a deepcopy of push rules before mutating them (diff)
downloadsynapse-47e7963e50704a1a981b8c009f8403085be721a6.tar.xz
Merge pull request #502 from matrix-org/erikj/push_notif_perf
Unread notification performance.
Diffstat (limited to 'synapse/handlers')
-rw-r--r--synapse/handlers/_base.py93
-rw-r--r--synapse/handlers/federation.py13
-rw-r--r--synapse/handlers/sync.py3
3 files changed, 60 insertions, 49 deletions
diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py
index bb2c6733d5..2d1167296a 100644
--- a/synapse/handlers/_base.py
+++ b/synapse/handlers/_base.py
@@ -53,16 +53,54 @@ class BaseHandler(object):
         self.event_builder_factory = hs.get_event_builder_factory()
 
     @defer.inlineCallbacks
-    def _filter_events_for_client(self, user_id, events, is_guest=False):
-        # Assumes that user has at some point joined the room if not is_guest.
+    def _filter_events_for_clients(self, users, events):
+        """ Returns dict of user_id -> list of events that user is allowed to
+        see.
+        """
+        event_id_to_state = yield self.store.get_state_for_events(
+            frozenset(e.event_id for e in events),
+            types=(
+                (EventTypes.RoomHistoryVisibility, ""),
+                (EventTypes.Member, None),
+            )
+        )
+
+        forgotten = yield defer.gatherResults([
+            self.store.who_forgot_in_room(
+                room_id,
+            )
+            for room_id in frozenset(e.room_id for e in events)
+        ], consumeErrors=True)
+
+        # Set of membership event_ids that have been forgotten
+        event_id_forgotten = frozenset(
+            row["event_id"] for rows in forgotten for row in rows
+        )
+
+        def allowed(event, user_id, is_guest):
+            state = event_id_to_state[event.event_id]
+
+            visibility_event = state.get((EventTypes.RoomHistoryVisibility, ""), None)
+            if visibility_event:
+                visibility = visibility_event.content.get("history_visibility", "shared")
+            else:
+                visibility = "shared"
 
-        def allowed(event, membership, visibility):
             if visibility == "world_readable":
                 return True
 
             if is_guest:
                 return False
 
+            membership_event = state.get((EventTypes.Member, user_id), None)
+            if membership_event:
+                if membership_event.event_id in event_id_forgotten:
+                    membership = None
+                else:
+                    membership = membership_event.membership
+            else:
+                membership = None
+
             if membership == Membership.JOIN:
                 return True
 
@@ -78,43 +116,20 @@ class BaseHandler(object):
 
             return True
 
-        event_id_to_state = yield self.store.get_state_for_events(
-            frozenset(e.event_id for e in events),
-            types=(
-                (EventTypes.RoomHistoryVisibility, ""),
-                (EventTypes.Member, user_id),
-            )
-        )
-
-        events_to_return = []
-        for event in events:
-            state = event_id_to_state[event.event_id]
+        defer.returnValue({
+            user_id: [
+                event
+                for event in events
+                if allowed(event, user_id, is_guest)
+            ]
+            for user_id, is_guest in users
+        })
 
-            membership_event = state.get((EventTypes.Member, user_id), None)
-            if membership_event:
-                was_forgotten_at_event = yield self.store.was_forgotten_at(
-                    membership_event.state_key,
-                    membership_event.room_id,
-                    membership_event.event_id
-                )
-                if was_forgotten_at_event:
-                    membership = None
-                else:
-                    membership = membership_event.membership
-            else:
-                membership = None
-
-            visibility_event = state.get((EventTypes.RoomHistoryVisibility, ""), None)
-            if visibility_event:
-                visibility = visibility_event.content.get("history_visibility", "shared")
-            else:
-                visibility = "shared"
-
-            should_include = allowed(event, membership, visibility)
-            if should_include:
-                events_to_return.append(event)
-
-        defer.returnValue(events_to_return)
+    @defer.inlineCallbacks
+    def _filter_events_for_client(self, user_id, events, is_guest=False):
+        # Assumes that user has at some point joined the room if not is_guest.
+        res = yield self._filter_events_for_clients([(user_id, is_guest)], events)
+        defer.returnValue(res.get(user_id, []))
 
     def ratelimit(self, user_id):
         time_now = self.clock.time()
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index 26402ea9cd..4b94940e99 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -36,7 +36,7 @@ from synapse.events.utils import prune_event
 
 from synapse.util.retryutils import NotRetryingDestination
 
-# from synapse.push.action_generator import ActionGenerator
+from synapse.push.action_generator import ActionGenerator
 
 from twisted.internet import defer
 
@@ -244,12 +244,11 @@ class FederationHandler(BaseHandler):
                     user = UserID.from_string(event.state_key)
                     yield user_joined_room(self.distributor, user, event.room_id)
 
-        # Temporarily disable notifications due to performance concerns.
-        # if not backfilled and not event.internal_metadata.is_outlier():
-        #     action_generator = ActionGenerator(self.store)
-        #     yield action_generator.handle_push_actions_for_event(
-        #         event, self
-        #     )
+        if not backfilled and not event.internal_metadata.is_outlier():
+            action_generator = ActionGenerator(self.store)
+            yield action_generator.handle_push_actions_for_event(
+                event, self
+            )
 
     @defer.inlineCallbacks
     def _filter_events_for_server(self, server_name, room_id, events):
diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py
index 1942268c3c..52202d8e63 100644
--- a/synapse/handlers/sync.py
+++ b/synapse/handlers/sync.py
@@ -841,9 +841,6 @@ class SyncHandler(BaseHandler):
 
     @defer.inlineCallbacks
     def unread_notifs_for_room_id(self, room_id, sync_config, ephemeral_by_room):
-        # Temporarily disable notifications due to performance concerns.
-        defer.returnValue([])
-
         last_unread_event_id = self.last_read_event_id_for_room_and_user(
             room_id, sync_config.user.to_string(), ephemeral_by_room
         )