Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 09be8ab

Browse files
authored
Remove the experimental implementation of MSC3772. (#14094)
MSC3772 has been abandoned.
1 parent 3f057e4 commit 09be8ab

File tree

12 files changed

+22
-365
lines changed

12 files changed

+22
-365
lines changed

changelog.d/14094.removal

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove the experimental implementation of [MSC3772](https://github.com/matrix-org/matrix-spec-proposals/pull/3772).

rust/src/push/base_rules.rs

-13
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,6 @@ pub const BASE_APPEND_UNDERRIDE_RULES: &[PushRule] = &[
257257
default: true,
258258
default_enabled: true,
259259
},
260-
PushRule {
261-
rule_id: Cow::Borrowed("global/underride/.org.matrix.msc3772.thread_reply"),
262-
priority_class: 1,
263-
conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::RelationMatch {
264-
rel_type: Cow::Borrowed("m.thread"),
265-
event_type_pattern: None,
266-
sender: None,
267-
sender_type: Some(Cow::Borrowed("user_id")),
268-
})]),
269-
actions: Cow::Borrowed(&[Action::Notify, HIGHLIGHT_FALSE_ACTION]),
270-
default: true,
271-
default_enabled: true,
272-
},
273260
PushRule {
274261
rule_id: Cow::Borrowed("global/underride/.m.rule.message"),
275262
priority_class: 1,

rust/src/push/evaluator.rs

+3-102
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::{
16-
borrow::Cow,
17-
collections::{BTreeMap, BTreeSet},
18-
};
15+
use std::collections::BTreeMap;
1916

2017
use anyhow::{Context, Error};
2118
use lazy_static::lazy_static;
@@ -49,13 +46,6 @@ pub struct PushRuleEvaluator {
4946
/// The `notifications` section of the current power levels in the room.
5047
notification_power_levels: BTreeMap<String, i64>,
5148

52-
/// The relations related to the event as a mapping from relation type to
53-
/// set of sender/event type 2-tuples.
54-
relations: BTreeMap<String, BTreeSet<(String, String)>>,
55-
56-
/// Is running "relation" conditions enabled?
57-
relation_match_enabled: bool,
58-
5949
/// The power level of the sender of the event, or None if event is an
6050
/// outlier.
6151
sender_power_level: Option<i64>,
@@ -70,8 +60,6 @@ impl PushRuleEvaluator {
7060
room_member_count: u64,
7161
sender_power_level: Option<i64>,
7262
notification_power_levels: BTreeMap<String, i64>,
73-
relations: BTreeMap<String, BTreeSet<(String, String)>>,
74-
relation_match_enabled: bool,
7563
) -> Result<Self, Error> {
7664
let body = flattened_keys
7765
.get("content.body")
@@ -83,8 +71,6 @@ impl PushRuleEvaluator {
8371
body,
8472
room_member_count,
8573
notification_power_levels,
86-
relations,
87-
relation_match_enabled,
8874
sender_power_level,
8975
})
9076
}
@@ -203,89 +189,11 @@ impl PushRuleEvaluator {
203189
false
204190
}
205191
}
206-
KnownCondition::RelationMatch {
207-
rel_type,
208-
event_type_pattern,
209-
sender,
210-
sender_type,
211-
} => {
212-
self.match_relations(rel_type, sender, sender_type, user_id, event_type_pattern)?
213-
}
214192
};
215193

216194
Ok(result)
217195
}
218196

219-
/// Evaluates a relation condition.
220-
fn match_relations(
221-
&self,
222-
rel_type: &str,
223-
sender: &Option<Cow<str>>,
224-
sender_type: &Option<Cow<str>>,
225-
user_id: Option<&str>,
226-
event_type_pattern: &Option<Cow<str>>,
227-
) -> Result<bool, Error> {
228-
// First check if relation matching is enabled...
229-
if !self.relation_match_enabled {
230-
return Ok(false);
231-
}
232-
233-
// ... and if there are any relations to match against.
234-
let relations = if let Some(relations) = self.relations.get(rel_type) {
235-
relations
236-
} else {
237-
return Ok(false);
238-
};
239-
240-
// Extract the sender pattern from the condition
241-
let sender_pattern = if let Some(sender) = sender {
242-
Some(sender.as_ref())
243-
} else if let Some(sender_type) = sender_type {
244-
if sender_type == "user_id" {
245-
if let Some(user_id) = user_id {
246-
Some(user_id)
247-
} else {
248-
return Ok(false);
249-
}
250-
} else {
251-
warn!("Unrecognized sender_type: {sender_type}");
252-
return Ok(false);
253-
}
254-
} else {
255-
None
256-
};
257-
258-
let mut sender_compiled_pattern = if let Some(pattern) = sender_pattern {
259-
Some(get_glob_matcher(pattern, GlobMatchType::Whole)?)
260-
} else {
261-
None
262-
};
263-
264-
let mut type_compiled_pattern = if let Some(pattern) = event_type_pattern {
265-
Some(get_glob_matcher(pattern, GlobMatchType::Whole)?)
266-
} else {
267-
None
268-
};
269-
270-
for (relation_sender, event_type) in relations {
271-
if let Some(pattern) = &mut sender_compiled_pattern {
272-
if !pattern.is_match(relation_sender)? {
273-
continue;
274-
}
275-
}
276-
277-
if let Some(pattern) = &mut type_compiled_pattern {
278-
if !pattern.is_match(event_type)? {
279-
continue;
280-
}
281-
}
282-
283-
return Ok(true);
284-
}
285-
286-
Ok(false)
287-
}
288-
289197
/// Evaluates a `event_match` condition.
290198
fn match_event_match(
291199
&self,
@@ -359,15 +267,8 @@ impl PushRuleEvaluator {
359267
fn push_rule_evaluator() {
360268
let mut flattened_keys = BTreeMap::new();
361269
flattened_keys.insert("content.body".to_string(), "foo bar bob hello".to_string());
362-
let evaluator = PushRuleEvaluator::py_new(
363-
flattened_keys,
364-
10,
365-
Some(0),
366-
BTreeMap::new(),
367-
BTreeMap::new(),
368-
true,
369-
)
370-
.unwrap();
270+
let evaluator =
271+
PushRuleEvaluator::py_new(flattened_keys, 10, Some(0), BTreeMap::new()).unwrap();
371272

372273
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"));
373274
assert_eq!(result.len(), 3);

rust/src/push/mod.rs

+8-36
Original file line numberDiff line numberDiff line change
@@ -275,16 +275,6 @@ pub enum KnownCondition {
275275
SenderNotificationPermission {
276276
key: Cow<'static, str>,
277277
},
278-
#[serde(rename = "org.matrix.msc3772.relation_match")]
279-
RelationMatch {
280-
rel_type: Cow<'static, str>,
281-
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
282-
event_type_pattern: Option<Cow<'static, str>>,
283-
#[serde(skip_serializing_if = "Option::is_none")]
284-
sender: Option<Cow<'static, str>>,
285-
#[serde(skip_serializing_if = "Option::is_none")]
286-
sender_type: Option<Cow<'static, str>>,
287-
},
288278
}
289279

290280
impl IntoPy<PyObject> for Condition {
@@ -401,21 +391,15 @@ impl PushRules {
401391
pub struct FilteredPushRules {
402392
push_rules: PushRules,
403393
enabled_map: BTreeMap<String, bool>,
404-
msc3772_enabled: bool,
405394
}
406395

407396
#[pymethods]
408397
impl FilteredPushRules {
409398
#[new]
410-
pub fn py_new(
411-
push_rules: PushRules,
412-
enabled_map: BTreeMap<String, bool>,
413-
msc3772_enabled: bool,
414-
) -> Self {
399+
pub fn py_new(push_rules: PushRules, enabled_map: BTreeMap<String, bool>) -> Self {
415400
Self {
416401
push_rules,
417402
enabled_map,
418-
msc3772_enabled,
419403
}
420404
}
421405

@@ -430,25 +414,13 @@ impl FilteredPushRules {
430414
/// Iterates over all the rules and their enabled state, including base
431415
/// rules, in the order they should be executed in.
432416
fn iter(&self) -> impl Iterator<Item = (&PushRule, bool)> {
433-
self.push_rules
434-
.iter()
435-
.filter(|rule| {
436-
// Ignore disabled experimental push rules
437-
if !self.msc3772_enabled
438-
&& rule.rule_id == "global/underride/.org.matrix.msc3772.thread_reply"
439-
{
440-
return false;
441-
}
442-
443-
true
444-
})
445-
.map(|r| {
446-
let enabled = *self
447-
.enabled_map
448-
.get(&*r.rule_id)
449-
.unwrap_or(&r.default_enabled);
450-
(r, enabled)
451-
})
417+
self.push_rules.iter().map(|r| {
418+
let enabled = *self
419+
.enabled_map
420+
.get(&*r.rule_id)
421+
.unwrap_or(&r.default_enabled);
422+
(r, enabled)
423+
})
452424
}
453425
}
454426

stubs/synapse/synapse_rust/push.pyi

+1-5
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ class PushRules:
2525
def rules(self) -> Collection[PushRule]: ...
2626

2727
class FilteredPushRules:
28-
def __init__(
29-
self, push_rules: PushRules, enabled_map: Dict[str, bool], msc3772_enabled: bool
30-
): ...
28+
def __init__(self, push_rules: PushRules, enabled_map: Dict[str, bool]): ...
3129
def rules(self) -> Collection[Tuple[PushRule, bool]]: ...
3230

3331
def get_base_rule_ids() -> Collection[str]: ...
@@ -39,8 +37,6 @@ class PushRuleEvaluator:
3937
room_member_count: int,
4038
sender_power_level: Optional[int],
4139
notification_power_levels: Mapping[str, int],
42-
relations: Mapping[str, Set[Tuple[str, str]]],
43-
relation_match_enabled: bool,
4440
): ...
4541
def run(
4642
self,

synapse/config/experimental.py

-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
9595
# MSC2815 (allow room moderators to view redacted event content)
9696
self.msc2815_enabled: bool = experimental.get("msc2815_enabled", False)
9797

98-
# MSC3772: A push rule for mutual relations.
99-
self.msc3772_enabled: bool = experimental.get("msc3772_enabled", False)
10098
# MSC3773: Thread notifications
10199
self.msc3773_enabled: bool = experimental.get("msc3773_enabled", False)
102100

synapse/push/bulk_push_rule_evaluator.py

+3-61
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,15 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
import itertools
1716
import logging
1817
from typing import (
1918
TYPE_CHECKING,
2019
Any,
2120
Collection,
2221
Dict,
23-
Iterable,
2422
List,
2523
Mapping,
2624
Optional,
27-
Set,
2825
Tuple,
2926
Union,
3027
)
@@ -38,7 +35,7 @@
3835
from synapse.state import POWER_KEY
3936
from synapse.storage.databases.main.roommember import EventIdMembership
4037
from synapse.storage.state import StateFilter
41-
from synapse.synapse_rust.push import FilteredPushRules, PushRule, PushRuleEvaluator
38+
from synapse.synapse_rust.push import FilteredPushRules, PushRuleEvaluator
4239
from synapse.util.caches import register_cache
4340
from synapse.util.metrics import measure_func
4441
from synapse.visibility import filter_event_for_clients_with_state
@@ -117,9 +114,6 @@ def __init__(self, hs: "HomeServer"):
117114
resizable=False,
118115
)
119116

120-
# Whether to support MSC3772 is supported.
121-
self._relations_match_enabled = self.hs.config.experimental.msc3772_enabled
122-
123117
async def _get_rules_for_event(
124118
self,
125119
event: EventBase,
@@ -200,51 +194,6 @@ async def _get_power_levels_and_sender_level(
200194

201195
return pl_event.content if pl_event else {}, sender_level
202196

203-
async def _get_mutual_relations(
204-
self, parent_id: str, rules: Iterable[Tuple[PushRule, bool]]
205-
) -> Dict[str, Set[Tuple[str, str]]]:
206-
"""
207-
Fetch event metadata for events which related to the same event as the given event.
208-
209-
If the given event has no relation information, returns an empty dictionary.
210-
211-
Args:
212-
parent_id: The event ID which is targeted by relations.
213-
rules: The push rules which will be processed for this event.
214-
215-
Returns:
216-
A dictionary of relation type to:
217-
A set of tuples of:
218-
The sender
219-
The event type
220-
"""
221-
222-
# If the experimental feature is not enabled, skip fetching relations.
223-
if not self._relations_match_enabled:
224-
return {}
225-
226-
# Pre-filter to figure out which relation types are interesting.
227-
rel_types = set()
228-
for rule, enabled in rules:
229-
if not enabled:
230-
continue
231-
232-
for condition in rule.conditions:
233-
if condition["kind"] != "org.matrix.msc3772.relation_match":
234-
continue
235-
236-
# rel_type is required.
237-
rel_type = condition.get("rel_type")
238-
if rel_type:
239-
rel_types.add(rel_type)
240-
241-
# If no valid rules were found, no mutual relations.
242-
if not rel_types:
243-
return {}
244-
245-
# If any valid rules were found, fetch the mutual relations.
246-
return await self.store.get_mutual_event_relations(parent_id, rel_types)
247-
248197
@measure_func("action_for_event_by_user")
249198
async def action_for_event_by_user(
250199
self, event: EventBase, context: EventContext
@@ -276,16 +225,11 @@ async def action_for_event_by_user(
276225
sender_power_level,
277226
) = await self._get_power_levels_and_sender_level(event, context)
278227

228+
# Find the event's thread ID.
279229
relation = relation_from_event(event)
280-
# If the event does not have a relation, then cannot have any mutual
281-
# relations or thread ID.
282-
relations = {}
230+
# If the event does not have a relation, then it cannot have a thread ID.
283231
thread_id = MAIN_TIMELINE
284232
if relation:
285-
relations = await self._get_mutual_relations(
286-
relation.parent_id,
287-
itertools.chain(*(r.rules() for r in rules_by_user.values())),
288-
)
289233
# Recursively attempt to find the thread this event relates to.
290234
if relation.rel_type == RelationTypes.THREAD:
291235
thread_id = relation.parent_id
@@ -306,8 +250,6 @@ async def action_for_event_by_user(
306250
room_member_count,
307251
sender_power_level,
308252
notification_levels,
309-
relations,
310-
self._relations_match_enabled,
311253
)
312254

313255
users = rules_by_user.keys()

0 commit comments

Comments
 (0)