Try stop with SIGINT first, pass timeout to constructor
This commit is contained in:
parent
2b754d2662
commit
21779b6d0d
@ -16,3 +16,24 @@ def test_watchdog_kill(caplog):
|
||||
log = ["Watchdog started", "Watchdog stopped"]
|
||||
for line in log:
|
||||
assert line in caplog.text
|
||||
|
||||
|
||||
def test_try_kill_failed(mocker):
|
||||
mocker.patch("os.kill")
|
||||
mocker.patch("os.waitpid", return_value=(0, 0))
|
||||
watchdog = Watchdog(1, 1)
|
||||
assert watchdog.try_kill(0) is False
|
||||
|
||||
|
||||
def test_try_kill_success(mocker):
|
||||
mocker.patch("os.kill")
|
||||
mocker.patch("os.waitpid", return_value=(0, 1))
|
||||
watchdog = Watchdog(1, 1)
|
||||
assert watchdog.try_kill(0) is True
|
||||
|
||||
|
||||
def test_try_kill_error(mocker):
|
||||
mocker.patch("os.kill")
|
||||
mocker.patch("os.waitpid", side_effect=OSError)
|
||||
watchdog = Watchdog(1, 1)
|
||||
assert watchdog.try_kill(0) is True
|
||||
|
@ -7,6 +7,7 @@ from multiprocessing import Value
|
||||
logger = logging.getLogger('freqtrade.watchdog')
|
||||
|
||||
WATCHDOG_TIMEOUT = 300
|
||||
KILL_TIMEOUT = 60
|
||||
|
||||
|
||||
class Watchdog:
|
||||
@ -14,8 +15,9 @@ class Watchdog:
|
||||
shared_heartbeat = Value('d', 0.0)
|
||||
kill_signal = None
|
||||
|
||||
def __init__(self, timeout=WATCHDOG_TIMEOUT):
|
||||
def __init__(self, timeout=WATCHDOG_TIMEOUT, kill_timeout=KILL_TIMEOUT):
|
||||
self.timeout = timeout
|
||||
self.kill_timeout = kill_timeout
|
||||
self.heartbeat()
|
||||
|
||||
def heartbeat(self) -> None:
|
||||
@ -26,11 +28,27 @@ class Watchdog:
|
||||
logger.warning("Kill signal: {}".format(signum))
|
||||
self.kill_signal = signum
|
||||
|
||||
def try_kill(self, pid):
|
||||
os.kill(pid, signal.SIGINT)
|
||||
for count in range(0, self.kill_timeout):
|
||||
try:
|
||||
pid, err_code = os.waitpid(pid, os.WNOHANG)
|
||||
if pid != 0 or err_code != 0:
|
||||
return True
|
||||
time.sleep(1)
|
||||
except OSError:
|
||||
return True
|
||||
return False
|
||||
|
||||
def kill(self, pid):
|
||||
logger.info("Stopping pid {}".format(pid))
|
||||
if pid:
|
||||
os.kill(pid, signal.SIGTERM) # Better use sigint and then sigterm?
|
||||
os.wait()
|
||||
if self.try_kill(pid):
|
||||
logger.info("Process finished gracefully")
|
||||
else:
|
||||
logger.warning("Process not responded, kill by SIGTERM")
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
os.wait()
|
||||
|
||||
def start(self) -> bool:
|
||||
pid = os.fork()
|
||||
|
Loading…
Reference in New Issue
Block a user