pause idel

This commit is contained in:
2025-12-10 10:31:59 -05:00
parent 25e8ce1885
commit e9c7f51f91
8 changed files with 166 additions and 93 deletions

View File

@ -1 +1 @@
BATCH_SIZE = 1000
BATCH_SIZE = 250

View File

@ -15,6 +15,32 @@ def run_once():
log_info("[INFO] Aucune course active.")
return
# -------------------------------------------------
# Appliquer les PAUSE_REQUEST avant tout traitement
# -------------------------------------------------
active_courses = get_active_con_ids(cur)
for con_id in active_courses:
engine_table = f"resultv2_{con_id}_lecture"
# Lire le statut actuel
cur.execute(f"SELECT process_status FROM `{engine_table}` LIMIT 1")
row = cur.fetchone()
if not row:
continue
status = (row["process_status"] or "").upper()
# Si CI4 a demandé une pause → Python applique la pause maintenant
if status == "PAUSE_REQUEST":
cur.execute(f"UPDATE `{engine_table}` SET process_status = 'PAUSE'")
cnx.commit()
log_info(f"[PAUSE APPLIED] con_id={con_id}")
for con_id in con_ids:
process_course(cur, cnx, con_id)
@ -30,4 +56,21 @@ def run_once():
if __name__ == "__main__":
run_once()
import time
import msvcrt # Spécifique Windows
log_info("[TEST MODE] Boucle continue — appuyer ENTER pour arrêter.")
try:
while True:
run_once()
time.sleep(0.5)
if msvcrt.kbhit(): # Une touche a été pressée
key = msvcrt.getch()
if key == b'\r': # ENTER = arrêt
log_info("[TEST MODE] Arrêt demandé via ENTER.")
break
except KeyboardInterrupt:
log_info("[TEST MODE] Arrêt via CTRL+C.")

View File

@ -9,6 +9,7 @@ from datetime import datetime, timezone
from zoneinfo import ZoneInfo
from decimal import Decimal
from engine.utils import format_temps_decimal
from engine.engine_components.regles import resolve_priority
LOCAL_TZ = ZoneInfo("America/Toronto")
@ -59,6 +60,30 @@ def process_course(cur, cnx, con_id: int):
engine_table = f"resultv2_{con_id}_lecture"
classement_table = f"resultv2_{con_id}_classement"
# -------------------------------------------------
# Pause
# -------------------------------------------------
# Lire le statut
cur.execute(f"SELECT process_status FROM `{engine_table}` LIMIT 1")
row = cur.fetchone()
status = (row["process_status"] or "").upper()
# Si une pause est demandée
if status == "PAUSE_REQUEST":
# Le moteur se met officiellement en PAUSE
cur.execute(f"UPDATE `{engine_table}` SET process_status = 'PAUSE'")
cnx.commit()
log_info(f"[PAUSE] con_id={con_id} — pause appliquée avant traitement.")
return
# Si déjà en pause → sortir immédiatement
if status == "PAUSE":
log_info(f"[PAUSE] con_id={con_id} — course déjà en pause.")
return
# -------------------------------------------------
# Lire dernier ID traité (mécanisme incremental)
# -------------------------------------------------
@ -84,6 +109,8 @@ def process_course(cur, cnx, con_id: int):
# -------------------------------------------------
for lec in lectures:
rcourse_id = int(lec["rcourse_id"])
chr_loc = lec["chrinfo_location"]
timestamp = Decimal(lec["chrinfo_time"])
@ -249,94 +276,4 @@ def compute_tour(cur, detail_table, tp_id, dossard):
return last_tour + 1, prev_ts
# -------------------------------------------------
# Règle de priorité : remplace, rejette, ou force tour
# -------------------------------------------------
def resolve_priority(
cur,
cnx,
detail_table,
tp_id,
dossard,
new_timestamp,
new_priority,
det_id,
tp_config
):
# -------------------------------------------------
# Lecture de la fenêtre backup pour priorité
# -------------------------------------------------
cfg = (
tp_config[tp_id]["config"]
.get("config_tp", {})
.get("clef_temp_bbk", [])
)
backup_window = 0
if cfg:
try:
backup_window = int(cfg[0]["value1"])
except:
backup_window = 0
log_debug(f"[resolve_priority] backup_window={backup_window}")
# -------------------------------------------------
# Si backup_window = 0 → toujours accepter
# -------------------------------------------------
if backup_window <= 0:
return 1, None, None, None
# -------------------------------------------------
# Recherche d'une lecture existante dans la fenêtre
# -------------------------------------------------
cur.execute(f"""
SELECT detail_id, controller_priority, timestamp_read, tour
FROM `{detail_table}`
WHERE tp_id = %s
AND cla_info_dossard = %s
AND status = 1
AND ABS(timestamp_read - %s) <= %s
LIMIT 1
""", (tp_id, dossard, str(new_timestamp), backup_window))
row = cur.fetchone()
# -------------------------------------------------
# Aucun doublon → accepter
# -------------------------------------------------
if not row:
return 1, None, None, None
old_id = row["detail_id"]
old_priority = row["controller_priority"]
old_tour = row["tour"]
# -------------------------------------------------
# Comparaison des priorités
# -------------------------------------------------
# Nouvelle lecture moins prioritaire → rejet
if new_priority > old_priority:
return 0, "LOWER_PRIORITY", det_id, None
# Nouvelle lecture plus prioritaire → remplacer
if new_priority < old_priority:
cur.execute(f"""
UPDATE `{detail_table}`
SET
status = 0,
reason_code = 'REPLACED_BY_HIGHER_PRIORITY',
reason_ref_id = %s
WHERE detail_id = %s
""", (det_id, old_id))
cnx.commit()
forced_tour = old_tour
return 1, None, None, forced_tour
# Même priorité → rejet
return 0, "EQUAL_PRIORITY", det_id, None

View File

@ -0,0 +1,93 @@
# regles.py
from engine.logger import log_info, log_debug
# -------------------------------------------------
# Règle de priorité : remplace, rejette, ou force tour
# -------------------------------------------------
def resolve_priority(
cur,
cnx,
detail_table,
tp_id,
dossard,
new_timestamp,
new_priority,
det_id,
tp_config
):
# -------------------------------------------------
# Lecture de la fenêtre backup pour priorité
# -------------------------------------------------
cfg = (
tp_config[tp_id]["config"]
.get("config_tp", {})
.get("clef_temp_bbk", [])
)
backup_window = 0
if cfg:
try:
backup_window = int(cfg[0]["value1"])
except:
backup_window = 0
log_debug(f"[resolve_priority] backup_window={backup_window}")
# -------------------------------------------------
# Si backup_window = 0 → toujours accepter
# -------------------------------------------------
if backup_window <= 0:
return 1, None, None, None
# -------------------------------------------------
# Recherche d'une lecture existante dans la fenêtre
# -------------------------------------------------
cur.execute(f"""
SELECT detail_id, controller_priority, timestamp_read, tour
FROM `{detail_table}`
WHERE tp_id = %s
AND cla_info_dossard = %s
AND status = 1
AND ABS(timestamp_read - %s) <= %s
LIMIT 1
""", (tp_id, dossard, str(new_timestamp), backup_window))
row = cur.fetchone()
# -------------------------------------------------
# Aucun doublon → accepter
# -------------------------------------------------
if not row:
return 1, None, None, None
old_id = row["detail_id"]
old_priority = row["controller_priority"]
old_tour = row["tour"]
# -------------------------------------------------
# Comparaison des priorités
# -------------------------------------------------
# Nouvelle lecture moins prioritaire → rejet
if new_priority > old_priority:
return 0, "LOWER_PRIORITY", det_id, None
# Nouvelle lecture plus prioritaire → remplacer
if new_priority < old_priority:
cur.execute(f"""
UPDATE `{detail_table}`
SET
status = 0,
reason_code = 'REPLACED_BY_HIGHER_PRIORITY',
reason_ref_id = %s
WHERE detail_id = %s
""", (det_id, old_id))
cnx.commit()
forced_tour = old_tour
return 1, None, None, forced_tour
# Même priorité → rejet
return 0, "EQUAL_PRIORITY", det_id, None