summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2021-01-28 19:42:41 +0000
committerErik Johnston <erik@matrix.org>2021-01-28 19:42:41 +0000
commitccdfa36131546c84bbc96e678f2c25f2a54d752a (patch)
tree3a40b4161869755466f5b5574524e538223a60ff
parentAdd smoother (diff)
downloadsynapse-ccdfa36131546c84bbc96e678f2c25f2a54d752a.tar.xz
Fixup
Diffstat (limited to '')
-rw-r--r--synapse/util/async_helpers.py16
-rw-r--r--tests/util/test_async_utils.py22
2 files changed, 25 insertions, 13 deletions
diff --git a/synapse/util/async_helpers.py b/synapse/util/async_helpers.py
index 34967bb414..b5843c6443 100644
--- a/synapse/util/async_helpers.py
+++ b/synapse/util/async_helpers.py
@@ -576,6 +576,8 @@ class Smoother:
         if not self._queue:
             return
 
+        self._next_call = None
+
         entry = self._queue.popleft()
         entry.defer.callback(None)
 
@@ -584,7 +586,6 @@ class Smoother:
 
         if not self._queue:
             scheduled_for_ms = (now + self._target_ms + self._last_run) / 2
-            print(scheduled_for_ms, now)
             if scheduled_for_ms <= now:
                 self._last_run = now
                 return
@@ -611,25 +612,26 @@ class Smoother:
             step = self._target_ms / (len(self._queue) + 1)
             for idx, entry in enumerate(self._queue):
                 new_time = now + (idx + 1) * step
-                print("Moving?", entry.scheduled_for_ms, new_time)
                 if new_time < entry.scheduled_for_ms:
                     entry.scheduled_for_ms = new_time
 
-        if self._next_call:
+        if self._next_call and not self._next_call.active:
             self._next_call.reset(
                 max(self._queue[0].scheduled_for_ms - now, 0) / 1000.0
             )
         else:
-            self._reactor.callLater(
+            self._next_call = self._reactor.callLater(
                 max(self._queue[0].scheduled_for_ms - now, 0) / 1000.0, self._fire_next
             )
 
         await make_deferred_yieldable(entry.defer)
+        now = self._reactor.seconds() * 1000.0
 
         self._last_run = now
 
-        self._reactor.callLater(
-            (self._queue[0].scheduled_for_ms - now) / 1000.0, self._fire_next,
-        )
+        if self._queue:
+            self._next_call = self._reactor.callLater(
+                (self._queue[0].scheduled_for_ms - now) / 1000.0, self._fire_next,
+            )
 
         return
diff --git a/tests/util/test_async_utils.py b/tests/util/test_async_utils.py
index 80a491e646..4eea05d7fe 100644
--- a/tests/util/test_async_utils.py
+++ b/tests/util/test_async_utils.py
@@ -122,18 +122,18 @@ class TestSmoother(TestCase):
     def test_multiple_at_same_time(self):
         self.clock.advance(100)
 
-        d = self.smoother.smooth()
-        self.successResultOf(d)
+        d1 = defer.ensureDeferred(self.smoother.smooth())
+        self.successResultOf(d1)
 
-        d = self.smoother.smooth()
-        self.assertNoResult(d)
+        d2 = defer.ensureDeferred(self.smoother.smooth())
+        self.assertNoResult(d2)
         self.assertAlmostEqual(
             self.smoother._queue[0].scheduled_for_ms,
             self.clock.seconds() * 1000 + self.smoother._target_ms / 2,
         )
 
-        d = self.smoother.smooth()
-        self.assertNoResult(d)
+        d3 = defer.ensureDeferred(self.smoother.smooth())
+        self.assertNoResult(d3)
         self.assertAlmostEqual(
             self.smoother._queue[0].scheduled_for_ms,
             self.clock.seconds() * 1000 + self.smoother._target_ms / 3,
@@ -143,6 +143,16 @@ class TestSmoother(TestCase):
             self.clock.seconds() * 1000 + 2 * self.smoother._target_ms / 3,
         )
 
+        self.clock.advance(4)
+        self.successResultOf(d2)
+        self.assertNoResult(d3)
+
+        self.clock.advance(0)
+        self.assertNoResult(d3)
+
+        self.clock.advance(4)
+        self.successResultOf(d3)
+
         self.clock.advance(100)
 
         self.assertNot(self.smoother._queue)