pause idel
This commit is contained in:
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
BATCH_SIZE = 1000
|
||||
BATCH_SIZE = 250
|
||||
@ -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.")
|
||||
|
||||
Binary file not shown.
BIN
engine/engine_components/__pycache__/regles.cpython-313.pyc
Normal file
BIN
engine/engine_components/__pycache__/regles.cpython-313.pyc
Normal file
Binary file not shown.
@ -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
|
||||
|
||||
93
engine/engine_components/regles.py
Normal file
93
engine/engine_components/regles.py
Normal 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
|
||||
Reference in New Issue
Block a user