diff --git a/changelog.d/12859.feature b/changelog.d/12859.feature
new file mode 100644
index 0000000000..e674c31ae8
--- /dev/null
+++ b/changelog.d/12859.feature
@@ -0,0 +1 @@
+Experimental support for [MSC3772](https://github.com/matrix-org/matrix-spec-proposals/pull/3772): Push rule for mutually related events.
diff --git a/synapse/storage/databases/main/relations.py b/synapse/storage/databases/main/relations.py
index 3b1b2ce6cb..b457bc189e 100644
--- a/synapse/storage/databases/main/relations.py
+++ b/synapse/storage/databases/main/relations.py
@@ -13,7 +13,6 @@
# limitations under the License.
import logging
-from collections import defaultdict
from typing import (
Collection,
Dict,
@@ -810,7 +809,9 @@ class RelationsWorkerStore(SQLBaseStore):
txn: LoggingTransaction,
) -> Dict[str, Set[Tuple[str, str]]]:
txn.execute(sql, [event_id] + rel_type_args)
- result = defaultdict(set)
+ result: Dict[str, Set[Tuple[str, str]]] = {
+ rel_type: set() for rel_type in relation_types
+ }
for rel_type, sender, type in txn.fetchall():
result[rel_type].add((sender, type))
return result
diff --git a/synapse/util/caches/descriptors.py b/synapse/util/caches/descriptors.py
index eda92d864d..867f315b2a 100644
--- a/synapse/util/caches/descriptors.py
+++ b/synapse/util/caches/descriptors.py
@@ -595,13 +595,14 @@ def cached(
def cachedList(
*, cached_method_name: str, list_name: str, num_args: Optional[int] = None
) -> Callable[[F], _CachedFunction[F]]:
- """Creates a descriptor that wraps a function in a `CacheListDescriptor`.
+ """Creates a descriptor that wraps a function in a `DeferredCacheListDescriptor`.
- Used to do batch lookups for an already created cache. A single argument
+ Used to do batch lookups for an already created cache. One of the arguments
is specified as a list that is iterated through to lookup keys in the
original cache. A new tuple consisting of the (deduplicated) keys that weren't in
- the cache gets passed to the original function, the result of which is stored in the
- cache.
+ the cache gets passed to the original function, which is expected to results
+ in a map of key to value for each passed value. THe new results are stored in the
+ original cache. Note that any missing values are cached as None.
Args:
cached_method_name: The name of the single-item lookup method.
@@ -614,11 +615,11 @@ def cachedList(
Example:
class Example:
- @cached(num_args=2)
- def do_something(self, first_arg):
+ @cached()
+ def do_something(self, first_arg, second_arg):
...
- @cachedList(do_something.cache, list_name="second_args", num_args=2)
+ @cachedList(cached_method_name="do_something", list_name="second_args")
def batch_do_something(self, first_arg, second_args):
...
"""
|