"""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)