From 8afb8154b24f0abe0f8f319300d3d1b45f14a207 Mon Sep 17 00:00:00 2001 From: Ivan Gotovchits Date: Mon, 7 Aug 2023 21:15:46 +0000 Subject: [PATCH 1/7] fixes EventDebouncer not producing events Resolves #997 --- src/watchdog/utils/event_debouncer.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/watchdog/utils/event_debouncer.py b/src/watchdog/utils/event_debouncer.py index 8fa317e6..b8f2a016 100644 --- a/src/watchdog/utils/event_debouncer.py +++ b/src/watchdog/utils/event_debouncer.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import time import threading from watchdog.utils import BaseThread @@ -39,13 +40,16 @@ def stop(self): def run(self): with self._cond: while True: + started = time.monotonic() # Wait for first event (or shutdown). self._cond.wait() - if self.debounce_interval_seconds: # Wait for additional events (or shutdown) until the debounce interval passes. while self.should_keep_running(): - if not self._cond.wait(timeout=self.debounce_interval_seconds): + if self._cond.wait(timeout=self.debounce_interval_seconds): + if (time.monotonic() - started > self.debounce_interval_seconds): + break + else: break if not self.should_keep_running(): From 85edd94805cf1cebcde04f7871da712fa95acc97 Mon Sep 17 00:00:00 2001 From: Ivan Gotovchits Date: Thu, 10 Aug 2023 13:13:07 +0000 Subject: [PATCH 2/7] simplfies and fixes the debouncer main loop Makes it more readable and fixes a few issues, see #999 and #1000 --- src/watchdog/utils/event_debouncer.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/watchdog/utils/event_debouncer.py b/src/watchdog/utils/event_debouncer.py index b8f2a016..cb483157 100644 --- a/src/watchdog/utils/event_debouncer.py +++ b/src/watchdog/utils/event_debouncer.py @@ -37,24 +37,27 @@ def stop(self): super().stop() self._cond.notify() + def time_to_flush(self, started): + return time.monotonic() - started > self.debounce_interval_seconds + def run(self): with self._cond: - while True: + while self.should_keep_running(): started = time.monotonic() - # Wait for first event (or shutdown). - self._cond.wait() if self.debounce_interval_seconds: - # Wait for additional events (or shutdown) until the debounce interval passes. while self.should_keep_running(): - if self._cond.wait(timeout=self.debounce_interval_seconds): - if (time.monotonic() - started > self.debounce_interval_seconds): - break - else: + timed_out = not self._cond.wait( + timeout=self.debounce_interval_seconds + ) + if timed_out or self.time_to_flush(started): break - - if not self.should_keep_running(): - break + else: + self._cond.wait() events = self._events self._events = [] self.events_callback(events) + + # send any events before leaving + if self._events: + self.events_callback(events) From ca36d2af495a2c10015ca03cd2b23da5742f869e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Sun, 28 Jul 2024 16:00:57 +0200 Subject: [PATCH 3/7] Update src/watchdog/utils/event_debouncer.py --- src/watchdog/utils/event_debouncer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/watchdog/utils/event_debouncer.py b/src/watchdog/utils/event_debouncer.py index cb483157..2b6deb9d 100644 --- a/src/watchdog/utils/event_debouncer.py +++ b/src/watchdog/utils/event_debouncer.py @@ -37,7 +37,7 @@ def stop(self): super().stop() self._cond.notify() - def time_to_flush(self, started): + def time_to_flush(self, started) -> bool: return time.monotonic() - started > self.debounce_interval_seconds def run(self): From 8b1726c71f29315a3d2ab88dcebedbaa9f0565d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Sun, 28 Jul 2024 16:04:11 +0200 Subject: [PATCH 4/7] Update src/watchdog/utils/event_debouncer.py --- src/watchdog/utils/event_debouncer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/watchdog/utils/event_debouncer.py b/src/watchdog/utils/event_debouncer.py index 2b6deb9d..9b21cb85 100644 --- a/src/watchdog/utils/event_debouncer.py +++ b/src/watchdog/utils/event_debouncer.py @@ -37,7 +37,7 @@ def stop(self): super().stop() self._cond.notify() - def time_to_flush(self, started) -> bool: + def time_to_flush(self, started: float) -> bool: return time.monotonic() - started > self.debounce_interval_seconds def run(self): From 66863ab60b2e7f6a5edfc366e7428b1ea558ae2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Sun, 28 Jul 2024 16:10:16 +0200 Subject: [PATCH 5/7] Update test_0_watchmedo.py --- tests/test_0_watchmedo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_0_watchmedo.py b/tests/test_0_watchmedo.py index c9fc5369..6269fcff 100644 --- a/tests/test_0_watchmedo.py +++ b/tests/test_0_watchmedo.py @@ -170,7 +170,7 @@ def test_auto_restart_on_file_change_debounce(tmpdir, capfd): time.sleep(1) trick.stop() cap = capfd.readouterr() - assert cap.out.splitlines(keepends=False).count("+++++ 0") == 3 + assert cap.out.splitlines(keepends=False).count("+++++ 0") == 4 assert trick.restart_count == 2 From b6d791f4f4cb46ed2e67c264b0054500ea722af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Sun, 28 Jul 2024 16:15:34 +0200 Subject: [PATCH 6/7] Update test_0_watchmedo.py --- tests/test_0_watchmedo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_0_watchmedo.py b/tests/test_0_watchmedo.py index 6269fcff..c9fc5369 100644 --- a/tests/test_0_watchmedo.py +++ b/tests/test_0_watchmedo.py @@ -170,7 +170,7 @@ def test_auto_restart_on_file_change_debounce(tmpdir, capfd): time.sleep(1) trick.stop() cap = capfd.readouterr() - assert cap.out.splitlines(keepends=False).count("+++++ 0") == 4 + assert cap.out.splitlines(keepends=False).count("+++++ 0") == 3 assert trick.restart_count == 2 From c7df2bf3e8eb68bef4b8b0e4be13e96a28dfbeaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Sun, 28 Jul 2024 16:22:52 +0200 Subject: [PATCH 7/7] Update event_debouncer.py --- src/watchdog/utils/event_debouncer.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/watchdog/utils/event_debouncer.py b/src/watchdog/utils/event_debouncer.py index 9b21cb85..281df22c 100644 --- a/src/watchdog/utils/event_debouncer.py +++ b/src/watchdog/utils/event_debouncer.py @@ -43,12 +43,10 @@ def time_to_flush(self, started: float) -> bool: def run(self): with self._cond: while self.should_keep_running(): - started = time.monotonic() if self.debounce_interval_seconds: + started = time.monotonic() while self.should_keep_running(): - timed_out = not self._cond.wait( - timeout=self.debounce_interval_seconds - ) + timed_out = not self._cond.wait(timeout=self.debounce_interval_seconds) if timed_out or self.time_to_flush(started): break else: @@ -58,6 +56,6 @@ def run(self): self._events = [] self.events_callback(events) - # send any events before leaving + # Send any events before leaving if self._events: self.events_callback(events)