82 lines
2.7 KiB
Python
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)
|