From dd1d0f6d8cd8acd3e2d06ae087c43377dd7b13c8 Mon Sep 17 00:00:00 2001 From: Alexander Udovichenko Date: Fri, 18 Oct 2024 16:59:04 +0300 Subject: [PATCH 1/6] Fix WheelTimer implementation can raise events early --- synapse/util/wheel_timer.py | 6 ++---- tests/util/test_wheel_timer.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/synapse/util/wheel_timer.py b/synapse/util/wheel_timer.py index 44b109bdfd6..95eb1d71859 100644 --- a/synapse/util/wheel_timer.py +++ b/synapse/util/wheel_timer.py @@ -47,7 +47,6 @@ def __init__(self, bucket_size: int = 5000) -> None: """ self.bucket_size: int = bucket_size self.entries: List[_Entry[T]] = [] - self.current_tick: int = 0 def insert(self, now: int, obj: T, then: int) -> None: """Inserts object into timer. @@ -78,11 +77,10 @@ def insert(self, now: int, obj: T, then: int) -> None: self.entries[max(min_key, then_key) - min_key].elements.add(obj) return - next_key = now_key + 1 if self.entries: - last_key = self.entries[-1].end_key + last_key = self.entries[-1].end_key + 1 else: - last_key = next_key + last_key = now_key + 1 # Handle the case when `then` is in the past and `entries` is empty. then_key = max(last_key, then_key) diff --git a/tests/util/test_wheel_timer.py b/tests/util/test_wheel_timer.py index 173a7cfaeca..619f28bf6cb 100644 --- a/tests/util/test_wheel_timer.py +++ b/tests/util/test_wheel_timer.py @@ -78,3 +78,16 @@ def test_insert_past_multi(self) -> None: self.assertListEqual(wheel.fetch(147), [obj2]) self.assertListEqual(wheel.fetch(200), [obj1]) self.assertListEqual(wheel.fetch(240), []) + + def test_multi_insert_then_past(self) -> None: + wheel: WheelTimer[object] = WheelTimer(bucket_size=5) + + obj1 = object() + obj2 = object() + obj3 = object() + wheel.insert(100, obj1, 150) + wheel.insert(100, obj2, 160) + wheel.insert(100, obj3, 155) + + self.assertListEqual(wheel.fetch(110), []) + self.assertListEqual(wheel.fetch(158), [obj1]) From f7770d3e5668cdf616be74ba1ae0d03495c25c7a Mon Sep 17 00:00:00 2001 From: Alexander Udovichenko Date: Fri, 18 Oct 2024 17:19:21 +0300 Subject: [PATCH 2/6] add changelog --- changelog.d/17850.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/17850.bugfix diff --git a/changelog.d/17850.bugfix b/changelog.d/17850.bugfix new file mode 100644 index 00000000000..600896e2ec7 --- /dev/null +++ b/changelog.d/17850.bugfix @@ -0,0 +1 @@ +Fix bug when some presence and typing timeouts can expire early \ No newline at end of file From 511f88eedaf033a397718f15deeb75accc77411b Mon Sep 17 00:00:00 2001 From: Alexander Udovichenko Date: Fri, 1 Nov 2024 08:48:41 +0300 Subject: [PATCH 3/6] Update changelog.d/17850.bugfix Co-authored-by: Eric Eastwood --- changelog.d/17850.bugfix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/17850.bugfix b/changelog.d/17850.bugfix index 600896e2ec7..8ea99c4ef9a 100644 --- a/changelog.d/17850.bugfix +++ b/changelog.d/17850.bugfix @@ -1 +1 @@ -Fix bug when some presence and typing timeouts can expire early \ No newline at end of file +Fix bug when some presence and typing timeouts can expire early. \ No newline at end of file From 2796a5a2b92bceb63cb1b94dd696d5495cbdc907 Mon Sep 17 00:00:00 2001 From: Alexander Udovichenko Date: Fri, 1 Nov 2024 16:04:09 +0300 Subject: [PATCH 4/6] Refactor wheel timer tests from object to strings --- tests/util/test_wheel_timer.py | 51 +++++++++++++--------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/tests/util/test_wheel_timer.py b/tests/util/test_wheel_timer.py index 619f28bf6cb..6b27d09b6cf 100644 --- a/tests/util/test_wheel_timer.py +++ b/tests/util/test_wheel_timer.py @@ -28,66 +28,55 @@ class WheelTimerTestCase(unittest.TestCase): def test_single_insert_fetch(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - obj = object() - wheel.insert(100, obj, 150) + wheel.insert(100, '1', 150) self.assertListEqual(wheel.fetch(101), []) self.assertListEqual(wheel.fetch(110), []) self.assertListEqual(wheel.fetch(120), []) self.assertListEqual(wheel.fetch(130), []) self.assertListEqual(wheel.fetch(149), []) - self.assertListEqual(wheel.fetch(156), [obj]) + self.assertListEqual(wheel.fetch(156), ['1']) self.assertListEqual(wheel.fetch(170), []) def test_multi_insert(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - obj1 = object() - obj2 = object() - obj3 = object() - wheel.insert(100, obj1, 150) - wheel.insert(105, obj2, 130) - wheel.insert(106, obj3, 160) + wheel.insert(100, '1', 150) + wheel.insert(105, '2', 130) + wheel.insert(106, '3', 160) self.assertListEqual(wheel.fetch(110), []) - self.assertListEqual(wheel.fetch(135), [obj2]) + self.assertListEqual(wheel.fetch(135), ['2']) self.assertListEqual(wheel.fetch(149), []) - self.assertListEqual(wheel.fetch(158), [obj1]) + self.assertListEqual(wheel.fetch(158), ['1']) self.assertListEqual(wheel.fetch(160), []) - self.assertListEqual(wheel.fetch(200), [obj3]) + self.assertListEqual(wheel.fetch(200), ['3']) self.assertListEqual(wheel.fetch(210), []) def test_insert_past(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - obj = object() - wheel.insert(100, obj, 50) - self.assertListEqual(wheel.fetch(120), [obj]) + wheel.insert(100, '1', 50) + self.assertListEqual(wheel.fetch(120), ['1']) def test_insert_past_multi(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - obj1 = object() - obj2 = object() - obj3 = object() - wheel.insert(100, obj1, 150) - wheel.insert(100, obj2, 140) - wheel.insert(100, obj3, 50) - self.assertListEqual(wheel.fetch(110), [obj3]) + wheel.insert(100, '1', 150) + wheel.insert(100, '2', 140) + wheel.insert(100, '3', 50) + self.assertListEqual(wheel.fetch(110), ['3']) self.assertListEqual(wheel.fetch(120), []) - self.assertListEqual(wheel.fetch(147), [obj2]) - self.assertListEqual(wheel.fetch(200), [obj1]) + self.assertListEqual(wheel.fetch(147), ['2']) + self.assertListEqual(wheel.fetch(200), ['1']) self.assertListEqual(wheel.fetch(240), []) def test_multi_insert_then_past(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - obj1 = object() - obj2 = object() - obj3 = object() - wheel.insert(100, obj1, 150) - wheel.insert(100, obj2, 160) - wheel.insert(100, obj3, 155) + wheel.insert(100, '1', 150) + wheel.insert(100, '2', 160) + wheel.insert(100, '3', 155) self.assertListEqual(wheel.fetch(110), []) - self.assertListEqual(wheel.fetch(158), [obj1]) + self.assertListEqual(wheel.fetch(158), ['1']) From e7c670d4af3b1c6bf614b3a6f57fc4e67ca187ac Mon Sep 17 00:00:00 2001 From: Alexander Udovichenko Date: Sat, 2 Nov 2024 09:22:26 +0300 Subject: [PATCH 5/6] lint fixes --- tests/util/test_wheel_timer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/util/test_wheel_timer.py b/tests/util/test_wheel_timer.py index 6b27d09b6cf..4e15691dcbe 100644 --- a/tests/util/test_wheel_timer.py +++ b/tests/util/test_wheel_timer.py @@ -70,13 +70,13 @@ def test_insert_past_multi(self) -> None: self.assertListEqual(wheel.fetch(147), ['2']) self.assertListEqual(wheel.fetch(200), ['1']) self.assertListEqual(wheel.fetch(240), []) - + def test_multi_insert_then_past(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) wheel.insert(100, '1', 150) wheel.insert(100, '2', 160) wheel.insert(100, '3', 155) - + self.assertListEqual(wheel.fetch(110), []) self.assertListEqual(wheel.fetch(158), ['1']) From 9b90ddb43eef2c5fdc85f14995afd0943fc7b895 Mon Sep 17 00:00:00 2001 From: Alexander Udovichenko Date: Tue, 5 Nov 2024 11:09:41 +0300 Subject: [PATCH 6/6] lint fixes --- tests/util/test_wheel_timer.py | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/util/test_wheel_timer.py b/tests/util/test_wheel_timer.py index 4e15691dcbe..6fa575a18e4 100644 --- a/tests/util/test_wheel_timer.py +++ b/tests/util/test_wheel_timer.py @@ -28,55 +28,55 @@ class WheelTimerTestCase(unittest.TestCase): def test_single_insert_fetch(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - wheel.insert(100, '1', 150) + wheel.insert(100, "1", 150) self.assertListEqual(wheel.fetch(101), []) self.assertListEqual(wheel.fetch(110), []) self.assertListEqual(wheel.fetch(120), []) self.assertListEqual(wheel.fetch(130), []) self.assertListEqual(wheel.fetch(149), []) - self.assertListEqual(wheel.fetch(156), ['1']) + self.assertListEqual(wheel.fetch(156), ["1"]) self.assertListEqual(wheel.fetch(170), []) def test_multi_insert(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - wheel.insert(100, '1', 150) - wheel.insert(105, '2', 130) - wheel.insert(106, '3', 160) + wheel.insert(100, "1", 150) + wheel.insert(105, "2", 130) + wheel.insert(106, "3", 160) self.assertListEqual(wheel.fetch(110), []) - self.assertListEqual(wheel.fetch(135), ['2']) + self.assertListEqual(wheel.fetch(135), ["2"]) self.assertListEqual(wheel.fetch(149), []) - self.assertListEqual(wheel.fetch(158), ['1']) + self.assertListEqual(wheel.fetch(158), ["1"]) self.assertListEqual(wheel.fetch(160), []) - self.assertListEqual(wheel.fetch(200), ['3']) + self.assertListEqual(wheel.fetch(200), ["3"]) self.assertListEqual(wheel.fetch(210), []) def test_insert_past(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - wheel.insert(100, '1', 50) - self.assertListEqual(wheel.fetch(120), ['1']) + wheel.insert(100, "1", 50) + self.assertListEqual(wheel.fetch(120), ["1"]) def test_insert_past_multi(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - wheel.insert(100, '1', 150) - wheel.insert(100, '2', 140) - wheel.insert(100, '3', 50) - self.assertListEqual(wheel.fetch(110), ['3']) + wheel.insert(100, "1", 150) + wheel.insert(100, "2", 140) + wheel.insert(100, "3", 50) + self.assertListEqual(wheel.fetch(110), ["3"]) self.assertListEqual(wheel.fetch(120), []) - self.assertListEqual(wheel.fetch(147), ['2']) - self.assertListEqual(wheel.fetch(200), ['1']) + self.assertListEqual(wheel.fetch(147), ["2"]) + self.assertListEqual(wheel.fetch(200), ["1"]) self.assertListEqual(wheel.fetch(240), []) def test_multi_insert_then_past(self) -> None: wheel: WheelTimer[object] = WheelTimer(bucket_size=5) - wheel.insert(100, '1', 150) - wheel.insert(100, '2', 160) - wheel.insert(100, '3', 155) + wheel.insert(100, "1", 150) + wheel.insert(100, "2", 160) + wheel.insert(100, "3", 155) self.assertListEqual(wheel.fetch(110), []) - self.assertListEqual(wheel.fetch(158), ['1']) + self.assertListEqual(wheel.fetch(158), ["1"])