Files

82 lines
2.7 KiB
Python

"""Non-blocking, cancellable batch checks while the desktop GUI is open."""
import queue
from .runner import ProcessRunner
CHECK_INTERVAL_MS = 5 * 60 * 1000
class BatchMonitor:
def __init__(self, scheduler, on_ready, on_status, on_output):
self.scheduler = scheduler
self.on_ready = on_ready
self.on_status = on_status
self.on_output = on_output
self.active = False
self.timer = None
self.runner = None
def start(self, command, cwd, environment, log_path):
if self.active:
return
self.arguments = (command, cwd, environment, log_path)
self.active = True
self._check()
def stop(self):
self.active = False
if self.timer is not None:
self.scheduler.after_cancel(self.timer)
self.timer = None
if self.runner is not None:
try:
self.runner.force_stop()
except OSError as exc:
self.on_output(f"Arrêt de la vérification : {exc}\n")
self.runner = None
self.on_status("Vérification automatique arrêtée.")
def _later(self):
self.timer = self.scheduler.after(CHECK_INTERVAL_MS, self._check)
def _check(self):
self.timer = None
if not self.active:
return
self.runner = ProcessRunner()
self.on_status("Vérification des batchs en cours…")
try:
self.runner.start(*self.arguments)
except (OSError, RuntimeError) as exc:
self.on_output(f"Vérification impossible : {exc}\n")
self.runner = None
self.on_status("Échec de la vérification. Nouvel essai dans 5 minutes.")
self._later()
return
self.timer = self.scheduler.after(100, self._poll)
def _poll(self):
self.timer = None
if not self.active or self.runner is None:
return
while True:
try:
event, payload = self.runner.events.get_nowait()
except queue.Empty:
break
if event in {"output", "runner_error"}:
self.on_output(str(payload))
elif event == "finished":
code, interrupted = payload
self.runner = None
if code == 0 and not interrupted:
self.active = False
self.on_status("Tous les résultats batch sont prêts.")
self.on_ready()
else:
self.on_status("Résultats pas encore prêts. Nouvelle vérification dans 5 minutes.")
self._later()
return
self.timer = self.scheduler.after(100, self._poll)