From 6329017e7b7b937d711ad64f8d247eb8fccf28dc Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Mon, 29 Aug 2022 16:43:45 -0500 Subject: [PATCH 1/3] Give the correct next event when the message timestamps are the same Discovered while working on https://github.com/matrix-org/synapse/pull/13589 and I had all the messages at the same timestamp Part of https://github.com/matrix-org/matrix-spec-proposals/pull/3030 --- synapse/storage/databases/main/events_worker.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py index 8a7cdb024d60..eb8f920ecaca 100644 --- a/synapse/storage/databases/main/events_worker.py +++ b/synapse/storage/databases/main/events_worker.py @@ -2111,10 +2111,19 @@ async def get_event_id_for_timestamp( AND room_id = ? /* Make sure event is not rejected */ AND rejections.event_id IS NULL - ORDER BY origin_server_ts %s + /** + * First sort by the message timestamp. If the message timestamps are the + * same, we want the message that logically comes "next" (before/after + * the given timestamp) based on the DAG and its topological order (`depth`). + * Finally, we can tie-break based on when it was received on the server + * (`stream_ordering`). + */ + ORDER BY origin_server_ts %s, depth %s, stream_ordering %s LIMIT 1; """ + # + def get_event_id_for_timestamp_txn(txn: LoggingTransaction) -> Optional[str]: if direction == "b": # Find closest event *before* a given timestamp. We use descending @@ -2130,7 +2139,8 @@ def get_event_id_for_timestamp_txn(txn: LoggingTransaction) -> Optional[str]: order = "ASC" txn.execute( - sql_template % (comparison_operator, order), (timestamp, room_id) + sql_template % (comparison_operator, order, order, order), + (timestamp, room_id), ) row = txn.fetchone() if row: From 47e2a40bf4a992d9ac0c89062f7cf302ec59f118 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Mon, 29 Aug 2022 16:46:42 -0500 Subject: [PATCH 2/3] Add changelog --- changelog.d/13658.bugfix | 1 + synapse/storage/databases/main/events_worker.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 changelog.d/13658.bugfix diff --git a/changelog.d/13658.bugfix b/changelog.d/13658.bugfix new file mode 100644 index 000000000000..17f340bcdaf4 --- /dev/null +++ b/changelog.d/13658.bugfix @@ -0,0 +1 @@ +Fix MSC3030 `/timestamp_to_event` endpoint returning the correct next event when the events have the same timestamp. diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py index eb8f920ecaca..9b997c304d5e 100644 --- a/synapse/storage/databases/main/events_worker.py +++ b/synapse/storage/databases/main/events_worker.py @@ -2122,8 +2122,6 @@ async def get_event_id_for_timestamp( LIMIT 1; """ - # - def get_event_id_for_timestamp_txn(txn: LoggingTransaction) -> Optional[str]: if direction == "b": # Find closest event *before* a given timestamp. We use descending From eadfde0767318403799d572ca5c88525e35878ca Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 30 Aug 2022 11:46:09 -0500 Subject: [PATCH 3/3] Better wording in changelog Co-authored-by: Sean Quah <8349537+squahtx@users.noreply.github.com> --- changelog.d/13658.bugfix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/13658.bugfix b/changelog.d/13658.bugfix index 17f340bcdaf4..8740f066bb24 100644 --- a/changelog.d/13658.bugfix +++ b/changelog.d/13658.bugfix @@ -1 +1 @@ -Fix MSC3030 `/timestamp_to_event` endpoint returning the correct next event when the events have the same timestamp. +Fix MSC3030 `/timestamp_to_event` endpoint to return the correct next event when the events have the same timestamp.