Return the main timeline for events which are not part of a thread. (#14140)

Fixes a bug where threaded receipts could not be sent for the
main timeline.
1.103.0-whithout-watcha
Patrick Cloke 2 years ago committed by GitHub
parent e4e55f8eef
commit 87099b6ea5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      changelog.d/14140.feature
  2. 2
      synapse/push/bulk_push_rule_evaluator.py
  3. 12
      synapse/storage/databases/main/relations.py

@ -0,0 +1 @@
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).

@ -236,7 +236,7 @@ class BulkPushRuleEvaluator:
else: else:
# Since the event has not yet been persisted we check whether # Since the event has not yet been persisted we check whether
# the parent is part of a thread. # the parent is part of a thread.
thread_id = await self.store.get_thread_id(relation.parent_id) or "main" thread_id = await self.store.get_thread_id(relation.parent_id)
# It's possible that old room versions have non-integer power levels (floats or # It's possible that old room versions have non-integer power levels (floats or
# strings). Workaround this by explicitly converting to int. # strings). Workaround this by explicitly converting to int.

@ -28,7 +28,7 @@ from typing import (
import attr import attr
from synapse.api.constants import RelationTypes from synapse.api.constants import MAIN_TIMELINE, RelationTypes
from synapse.events import EventBase from synapse.events import EventBase
from synapse.storage._base import SQLBaseStore from synapse.storage._base import SQLBaseStore
from synapse.storage.database import LoggingTransaction, make_in_list_sql_clause from synapse.storage.database import LoggingTransaction, make_in_list_sql_clause
@ -777,7 +777,7 @@ class RelationsWorkerStore(SQLBaseStore):
) )
@cached() @cached()
async def get_thread_id(self, event_id: str) -> Optional[str]: async def get_thread_id(self, event_id: str) -> str:
""" """
Get the thread ID for an event. This considers multi-level relations, Get the thread ID for an event. This considers multi-level relations,
e.g. an annotation to an event which is part of a thread. e.g. an annotation to an event which is part of a thread.
@ -787,7 +787,7 @@ class RelationsWorkerStore(SQLBaseStore):
Returns: Returns:
The event ID of the root event in the thread, if this event is part The event ID of the root event in the thread, if this event is part
of a thread. None, otherwise. of a thread. "main", otherwise.
""" """
# Since event relations form a tree, we should only ever find 0 or 1 # Since event relations form a tree, we should only ever find 0 or 1
# results from the below query. # results from the below query.
@ -802,13 +802,15 @@ class RelationsWorkerStore(SQLBaseStore):
) SELECT relates_to_id FROM related_events WHERE relation_type = 'm.thread'; ) SELECT relates_to_id FROM related_events WHERE relation_type = 'm.thread';
""" """
def _get_thread_id(txn: LoggingTransaction) -> Optional[str]: def _get_thread_id(txn: LoggingTransaction) -> str:
txn.execute(sql, (event_id,)) txn.execute(sql, (event_id,))
# TODO Should we ensure there's only a single result here? # TODO Should we ensure there's only a single result here?
row = txn.fetchone() row = txn.fetchone()
if row: if row:
return row[0] return row[0]
return None
# If no thread was found, it is part of the main timeline.
return MAIN_TIMELINE
return await self.db_pool.runInteraction("get_thread_id", _get_thread_id) return await self.db_pool.runInteraction("get_thread_id", _get_thread_id)

Loading…
Cancel
Save