diff --git a/synapse/push/action_generator.py b/synapse/push/action_generator.py
index 4cf94f6c61..1d2e558f9a 100644
--- a/synapse/push/action_generator.py
+++ b/synapse/push/action_generator.py
@@ -25,8 +25,9 @@ logger = logging.getLogger(__name__)
class ActionGenerator:
- def __init__(self, store):
- self.store = store
+ def __init__(self, hs):
+ self.hs = hs
+ self.store = hs.get_datastore()
# really we want to get all user ids and all profile tags too,
# since we want the actions for each profile tag for every user and
# also actions for a client with no profile tag for each user.
@@ -42,7 +43,7 @@ class ActionGenerator:
)
bulk_evaluator = yield bulk_push_rule_evaluator.evaluator_for_room_id(
- event.room_id, self.store
+ event.room_id, self.hs, self.store
)
actions_by_user = yield bulk_evaluator.action_for_event_by_user(event, handler)
diff --git a/synapse/push/bulk_push_rule_evaluator.py b/synapse/push/bulk_push_rule_evaluator.py
index efd686fa6e..1000ae6301 100644
--- a/synapse/push/bulk_push_rule_evaluator.py
+++ b/synapse/push/bulk_push_rule_evaluator.py
@@ -36,6 +36,7 @@ def decode_rule_json(rule):
@defer.inlineCallbacks
def _get_rules(room_id, user_ids, store):
rules_by_user = yield store.bulk_get_push_rules(user_ids)
+
rules_by_user = {
uid: baserules.list_with_base_rules([
decode_rule_json(rule_list)
@@ -47,12 +48,16 @@ def _get_rules(room_id, user_ids, store):
@defer.inlineCallbacks
-def evaluator_for_room_id(room_id, store):
- users = yield store.get_users_in_room(room_id)
- rules_by_user = yield _get_rules(room_id, users, store)
+def evaluator_for_room_id(room_id, hs, store):
+ results = yield store.get_receipts_for_room(room_id, "m.read")
+ user_ids = [
+ row["user_id"] for row in results
+ if hs.is_mine_id(row["user_id"])
+ ]
+ rules_by_user = yield _get_rules(room_id, user_ids, store)
defer.returnValue(BulkPushRuleEvaluator(
- room_id, rules_by_user, users, store
+ room_id, rules_by_user, user_ids, store
))
@@ -129,7 +134,7 @@ def _condition_checker(evaluator, conditions, uid, display_name, cache):
res = evaluator.matches(cond, uid, display_name, None)
if _id:
- cache[_id] = res
+ cache[_id] = bool(res)
if not res:
return False
diff --git a/synapse/push/push_rule_evaluator.py b/synapse/push/push_rule_evaluator.py
index 4654994d2d..753b6469e2 100644
--- a/synapse/push/push_rule_evaluator.py
+++ b/synapse/push/push_rule_evaluator.py
@@ -22,6 +22,7 @@ import simplejson as json
import re
from synapse.types import UserID
+from synapse.util.caches.lrucache import LruCache
logger = logging.getLogger(__name__)
@@ -277,18 +278,18 @@ def _glob_matches(glob, value, word_boundary=False):
)
if word_boundary:
r = r"\b%s\b" % (r,)
- r = re.compile(r, flags=re.IGNORECASE)
+ r = _compile_regex(r)
return r.search(value)
else:
r = r + "$"
- r = re.compile(r, flags=re.IGNORECASE)
+ r = _compile_regex(r)
return r.match(value)
elif word_boundary:
r = re.escape(glob)
r = r"\b%s\b" % (r,)
- r = re.compile(r, flags=re.IGNORECASE)
+ r = _compile_regex(r)
return r.search(value)
else:
@@ -306,3 +307,16 @@ def _flatten_dict(d, prefix=[], result={}):
_flatten_dict(value, prefix=(prefix+[key]), result=result)
return result
+
+
+regex_cache = LruCache(100000)
+
+
+def _compile_regex(regex_str):
+ r = regex_cache.get(regex_str, None)
+ if r:
+ return r
+
+ r = re.compile(regex_str, flags=re.IGNORECASE)
+ regex_cache[regex_str] = r
+ return r
|