From 378d3b2e32108f87889747da0598a50aee68d766 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sun, 21 Mar 2021 02:47:05 +0100 Subject: [PATCH 1/4] Unxfail test_daemonize --- magicbus/test/test_opsys.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/magicbus/test/test_opsys.py b/magicbus/test/test_opsys.py index 1dbdbdd1..3f33c48e 100644 --- a/magicbus/test/test_opsys.py +++ b/magicbus/test/test_opsys.py @@ -33,17 +33,6 @@ def do_GET(self): service = WebService(handler_class=Handler) -@pytest.mark.xfail( - sys.version_info[0] > 2, reason=""" - Hangs under Python 3 because it loops too fast causing a race - condition in `magicbus.plugins.opsys.PIDFile.join()`. - - Refs: - * https://github.com/cherrypy/magicbus/issues/7 - * https://github.com/cherrypy/magicbus/pull/8 - """, - run=False, -) @pytest.mark.skipif(os.name != 'posix', reason='not on POSIX') def test_daemonize(): # Spawn the process and wait, when this returns, the original process From 6f589c4519534eac19c405bdb693f2ca410c7e4c Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 11 Mar 2020 21:03:43 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=9A=91=20Check=20for=20a=20replaced?= =?UTF-8?q?=20PID=20file=20in=20join?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch works around an issue described in cherrypy/magicbus#7 by also comparing the stat of PID files. Otherwise it misses cases when PID file gets recreated faster that the check loop hits another existence check. --- magicbus/plugins/opsys.py | 12 ++++++++++-- magicbus/test/test_signals.py | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/magicbus/plugins/opsys.py b/magicbus/plugins/opsys.py index 4be4ff3c..7a1c8335 100644 --- a/magicbus/plugins/opsys.py +++ b/magicbus/plugins/opsys.py @@ -265,8 +265,16 @@ def wait(self, timeout=None, poll_interval=0.1): def join(self, timeout=None, poll_interval=0.1): """Return when the PID file does not exist, or the timeout expires.""" + try: + initial_stat = os.stat(self.pidfile) + except OSError: # file does not exist + return + starttime = time.time() while timeout is None or time.time() - starttime <= timeout: - if not os.path.exists(self.pidfile): - return + try: + if initial_stat != os.stat(self.pidfile): + return # file has been changed/replaced + except OSError: + return # file does not exist time.sleep(poll_interval) diff --git a/magicbus/test/test_signals.py b/magicbus/test/test_signals.py index 526288d4..ad309886 100644 --- a/magicbus/test/test_signals.py +++ b/magicbus/test/test_signals.py @@ -56,6 +56,7 @@ def test_SIGHUP_daemonized(): kill(pid, SIGHUP) # Give the server some time to restart + pidfile.join() time.sleep(1) for _ in range(6): new_pid = pidfile.wait(5) From 3589148ea3047fa863a707eadd15d18898547c70 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 11 Mar 2020 21:18:10 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=8E=A8=E2=99=BB=20Specifically=20chec?= =?UTF-8?q?k=20for=20PID=20creation=20time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- magicbus/plugins/opsys.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/magicbus/plugins/opsys.py b/magicbus/plugins/opsys.py index 7a1c8335..9072c446 100644 --- a/magicbus/plugins/opsys.py +++ b/magicbus/plugins/opsys.py @@ -270,11 +270,20 @@ def join(self, timeout=None, poll_interval=0.1): except OSError: # file does not exist return + initial_creation_time = initial_stat.st_ctime + starttime = time.time() while timeout is None or time.time() - starttime <= timeout: try: - if initial_stat != os.stat(self.pidfile): - return # file has been changed/replaced + pid_stat = os.stat(self.pidfile) except OSError: return # file does not exist + + pid_creation_time = pid_stat.st_ctime + if pid_creation_time > initial_creation_time: + return # file has been replaced + + if pid_stat != initial_stat: + return # file has been changed + time.sleep(poll_interval) From 905b42a3c0d659296a629e1d3fb30aaa5dc1bdc7 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 11 Mar 2020 21:22:30 +0100 Subject: [PATCH 4/4] Skip comparing the whole stat obj --- magicbus/plugins/opsys.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/magicbus/plugins/opsys.py b/magicbus/plugins/opsys.py index 9072c446..bd35f974 100644 --- a/magicbus/plugins/opsys.py +++ b/magicbus/plugins/opsys.py @@ -283,7 +283,4 @@ def join(self, timeout=None, poll_interval=0.1): if pid_creation_time > initial_creation_time: return # file has been replaced - if pid_stat != initial_stat: - return # file has been changed - time.sleep(poll_interval)