summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--changelog.d/18391.bugfix1
-rw-r--r--synapse/handlers/device.py13
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