2 files changed, 6 insertions, 8 deletions
diff --git a/changelog.d/18391.bugfix b/changelog.d/18391.bugfix
new file mode 100644
index 0000000000..bbcb7b7a28
--- /dev/null
+++ b/changelog.d/18391.bugfix
@@ -0,0 +1 @@
+Prevent race-condition in `_maybe_retry_device_resync` entrance.
diff --git a/synapse/handlers/device.py b/synapse/handlers/device.py
index 1efd039f22..f8b547bbed 100644
--- a/synapse/handlers/device.py
+++ b/synapse/handlers/device.py
@@ -20,6 +20,7 @@
#
#
import logging
+from threading import Lock
from typing import (
TYPE_CHECKING,
AbstractSet,
@@ -1237,7 +1238,7 @@ class DeviceListUpdater(DeviceListWorkerUpdater):
)
# Attempt to resync out of sync device lists every 30s.
- self._resync_retry_in_progress = False
+ self._resync_retry_lock = Lock()
self.clock.looping_call(
run_as_background_process,
30 * 1000,
@@ -1419,13 +1420,10 @@ class DeviceListUpdater(DeviceListWorkerUpdater):
"""Retry to resync device lists that are out of sync, except if another retry is
in progress.
"""
- if self._resync_retry_in_progress:
+ # If the lock can not be acquired we want to always return immediately instead of blocking here
+ if not self._resync_retry_lock.acquire(blocking=False):
return
-
try:
- # Prevent another call of this function to retry resyncing device lists so
- # we don't send too many requests.
- self._resync_retry_in_progress = True
# Get all of the users that need resyncing.
need_resync = await self.store.get_user_ids_requiring_device_list_resync()
@@ -1466,8 +1464,7 @@ class DeviceListUpdater(DeviceListWorkerUpdater):
e,
)
finally:
- # Allow future calls to retry resyncinc out of sync device lists.
- self._resync_retry_in_progress = False
+ self._resync_retry_lock.release()
async def multi_user_device_resync(
self, user_ids: List[str], mark_failed_as_stale: bool = True
|