mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-04 08:54:59 -04:00
Make push rules use proper structures. (#13522)
This improves load times for push rules: | Version | Time per user | Time for 1k users | | -------------------- | ------------- | ----------------- | | Before | 138 µs | 138ms | | Now (with custom) | 2.11 µs | 2.11ms | | Now (without custom) | 49.7 ns | 0.05 ms | This therefore has a large impact on send times for rooms with large numbers of local users in the room.
This commit is contained in:
parent
d642ce4b32
commit
5442891cbc
8 changed files with 495 additions and 334 deletions
|
@ -18,16 +18,15 @@ from typing import Any, Dict, List, Optional
|
|||
from synapse.push.rulekinds import PRIORITY_CLASS_INVERSE_MAP, PRIORITY_CLASS_MAP
|
||||
from synapse.types import UserID
|
||||
|
||||
from .baserules import FilteredPushRules, PushRule
|
||||
|
||||
|
||||
def format_push_rules_for_user(
|
||||
user: UserID, ruleslist: List
|
||||
user: UserID, ruleslist: FilteredPushRules
|
||||
) -> Dict[str, Dict[str, list]]:
|
||||
"""Converts a list of rawrules and a enabled map into nested dictionaries
|
||||
to match the Matrix client-server format for push rules"""
|
||||
|
||||
# We're going to be mutating this a lot, so do a deep copy
|
||||
ruleslist = copy.deepcopy(ruleslist)
|
||||
|
||||
rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {
|
||||
"global": {},
|
||||
"device": {},
|
||||
|
@ -35,11 +34,30 @@ def format_push_rules_for_user(
|
|||
|
||||
rules["global"] = _add_empty_priority_class_arrays(rules["global"])
|
||||
|
||||
for r in ruleslist:
|
||||
template_name = _priority_class_to_template_name(r["priority_class"])
|
||||
for r, enabled in ruleslist:
|
||||
template_name = _priority_class_to_template_name(r.priority_class)
|
||||
|
||||
rulearray = rules["global"][template_name]
|
||||
|
||||
template_rule = _rule_to_template(r)
|
||||
if not template_rule:
|
||||
continue
|
||||
|
||||
rulearray.append(template_rule)
|
||||
|
||||
template_rule["enabled"] = enabled
|
||||
|
||||
if "conditions" not in template_rule:
|
||||
# Not all formatted rules have explicit conditions, e.g. "room"
|
||||
# rules omit them as they can be derived from the kind and rule ID.
|
||||
#
|
||||
# If the formatted rule has no conditions then we can skip the
|
||||
# formatting of conditions.
|
||||
continue
|
||||
|
||||
# Remove internal stuff.
|
||||
for c in r["conditions"]:
|
||||
template_rule["conditions"] = copy.deepcopy(template_rule["conditions"])
|
||||
for c in template_rule["conditions"]:
|
||||
c.pop("_cache_key", None)
|
||||
|
||||
pattern_type = c.pop("pattern_type", None)
|
||||
|
@ -52,16 +70,6 @@ def format_push_rules_for_user(
|
|||
if sender_type == "user_id":
|
||||
c["sender"] = user.to_string()
|
||||
|
||||
rulearray = rules["global"][template_name]
|
||||
|
||||
template_rule = _rule_to_template(r)
|
||||
if template_rule:
|
||||
if "enabled" in r:
|
||||
template_rule["enabled"] = r["enabled"]
|
||||
else:
|
||||
template_rule["enabled"] = True
|
||||
rulearray.append(template_rule)
|
||||
|
||||
return rules
|
||||
|
||||
|
||||
|
@ -71,24 +79,24 @@ def _add_empty_priority_class_arrays(d: Dict[str, list]) -> Dict[str, list]:
|
|||
return d
|
||||
|
||||
|
||||
def _rule_to_template(rule: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
||||
unscoped_rule_id = None
|
||||
if "rule_id" in rule:
|
||||
unscoped_rule_id = _rule_id_from_namespaced(rule["rule_id"])
|
||||
def _rule_to_template(rule: PushRule) -> Optional[Dict[str, Any]]:
|
||||
templaterule: Dict[str, Any]
|
||||
|
||||
template_name = _priority_class_to_template_name(rule["priority_class"])
|
||||
unscoped_rule_id = _rule_id_from_namespaced(rule.rule_id)
|
||||
|
||||
template_name = _priority_class_to_template_name(rule.priority_class)
|
||||
if template_name in ["override", "underride"]:
|
||||
templaterule = {k: rule[k] for k in ["conditions", "actions"]}
|
||||
templaterule = {"conditions": rule.conditions, "actions": rule.actions}
|
||||
elif template_name in ["sender", "room"]:
|
||||
templaterule = {"actions": rule["actions"]}
|
||||
unscoped_rule_id = rule["conditions"][0]["pattern"]
|
||||
templaterule = {"actions": rule.actions}
|
||||
unscoped_rule_id = rule.conditions[0]["pattern"]
|
||||
elif template_name == "content":
|
||||
if len(rule["conditions"]) != 1:
|
||||
if len(rule.conditions) != 1:
|
||||
return None
|
||||
thecond = rule["conditions"][0]
|
||||
thecond = rule.conditions[0]
|
||||
if "pattern" not in thecond:
|
||||
return None
|
||||
templaterule = {"actions": rule["actions"]}
|
||||
templaterule = {"actions": rule.actions}
|
||||
templaterule["pattern"] = thecond["pattern"]
|
||||
else:
|
||||
# This should not be reached unless this function is not kept in sync
|
||||
|
@ -97,8 +105,8 @@ def _rule_to_template(rule: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|||
|
||||
if unscoped_rule_id:
|
||||
templaterule["rule_id"] = unscoped_rule_id
|
||||
if "default" in rule:
|
||||
templaterule["default"] = rule["default"]
|
||||
if rule.default:
|
||||
templaterule["default"] = True
|
||||
return templaterule
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue