From 299b00d968ee23ba4e4806dd7c4fa97c7fcfb6f5 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 27 Sep 2022 15:17:41 +0100 Subject: [PATCH] Prioritize outbound to-device over device list updates (#13922) Otherwise device list changes for large accounts can temporarily delay to-device messages. --- changelog.d/13922.bugfix | 1 + .../sender/per_destination_queue.py | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 changelog.d/13922.bugfix diff --git a/changelog.d/13922.bugfix b/changelog.d/13922.bugfix new file mode 100644 index 000000000..7269d28de --- /dev/null +++ b/changelog.d/13922.bugfix @@ -0,0 +1 @@ +Fix long-standing bug where device updates could cause delays sending out to-device messages over federation. diff --git a/synapse/federation/sender/per_destination_queue.py b/synapse/federation/sender/per_destination_queue.py index 41d8b937a..084c45a95 100644 --- a/synapse/federation/sender/per_destination_queue.py +++ b/synapse/federation/sender/per_destination_queue.py @@ -646,10 +646,25 @@ class _TransactionQueueManager: # We start by fetching device related EDUs, i.e device updates and to # device messages. We have to keep 2 free slots for presence and rr_edus. - limit = MAX_EDUS_PER_TRANSACTION - 2 + device_edu_limit = MAX_EDUS_PER_TRANSACTION - 2 + + # We prioritize to-device messages so that existing encryption channels + # work. We also keep a few slots spare (by reducing the limit) so that + # we can still trickle out some device list updates. + ( + to_device_edus, + device_stream_id, + ) = await self.queue._get_to_device_message_edus(device_edu_limit - 10) + + if to_device_edus: + self._device_stream_id = device_stream_id + else: + self.queue._last_device_stream_id = device_stream_id + + device_edu_limit -= len(to_device_edus) device_update_edus, dev_list_id = await self.queue._get_device_update_edus( - limit + device_edu_limit ) if device_update_edus: @@ -657,18 +672,6 @@ class _TransactionQueueManager: else: self.queue._last_device_list_stream_id = dev_list_id - limit -= len(device_update_edus) - - ( - to_device_edus, - device_stream_id, - ) = await self.queue._get_to_device_message_edus(limit) - - if to_device_edus: - self._device_stream_id = device_stream_id - else: - self.queue._last_device_stream_id = device_stream_id - pending_edus = device_update_edus + to_device_edus # Now add the read receipt EDU.