поправленны правильные переходы из live в offline матчи в тредах и статусе

This commit is contained in:
2025-11-01 16:17:13 +03:00
parent cae769d3cb
commit 7152ac608f

View File

@@ -91,6 +91,8 @@ SEASON = None
GAME_START_DT = None # datetime начала матча (локальная из календаря) GAME_START_DT = None # datetime начала матча (локальная из календаря)
GAME_TODAY = False # флаг: игра сегодня GAME_TODAY = False # флаг: игра сегодня
GAME_SOON = False # флаг: игра сегодня и скоро (<1 часа) GAME_SOON = False # флаг: игра сегодня и скоро (<1 часа)
OFFLINE_SWITCH_AT = None # timestamp, когда надо уйти в оффлайн
OFFLINE_DELAY_SEC = 600 # 10 минут
# общая очередь # общая очередь
results_q = queue.Queue() results_q = queue.Queue()
@@ -129,10 +131,11 @@ def start_offline_threads(season, game_id):
global threads_offline, CURRENT_THREADS_MODE, stop_event_offline, latest_data global threads_offline, CURRENT_THREADS_MODE, stop_event_offline, latest_data
if CURRENT_THREADS_MODE == "offline": if CURRENT_THREADS_MODE == "offline":
logger.debug("[threads] already in OFFLINE mode → skip start_offline_threads")
return return
stop_live_threads() stop_live_threads()
logger.info("[threads] switching to OFFLINE mode ...")
# 🔹 очищаем latest_data безопасно, чтобы не ломать структуру # 🔹 очищаем latest_data безопасно, чтобы не ломать структуру
keep_keys = { keep_keys = {
"game", "game",
@@ -267,12 +270,24 @@ def stop_live_threads():
"""Гасим только live-треды.""" """Гасим только live-треды."""
global threads_live global threads_live
if not threads_live: if not threads_live:
logger.info("[threads] LIVE threads stopped (nothing to stop)")
return return
logger.info(f"[threads] Stopping {len(threads_live)} LIVE thread(s)...")
stop_event_live.set() stop_event_live.set()
still_alive = []
for t in threads_live: for t in threads_live:
t.join(timeout=1) t.join(timeout=2)
if t.is_alive():
logger.warning(f"[threads] LIVE thread is still alive: {t.name}")
still_alive.append(t.name)
threads_live = [] threads_live = []
logger.info("[threads] LIVE threads stopped") if still_alive:
logger.warning(f"[threads] Some LIVE threads did not stop: {still_alive}")
else:
logger.info("[threads] LIVE threads stopped")
def stop_offline_threads(): def stop_offline_threads():
@@ -333,6 +348,16 @@ def get_data_from_API(
# Получение результатов из всех запущенных потоков # Получение результатов из всех запущенных потоков
def results_consumer(): def results_consumer():
while not stop_event.is_set(): while not stop_event.is_set():
# ⬇️ проверяем, не пора ли в оффлайн (отложенный переход)
off_at = globals().get("OFFLINE_SWITCH_AT")
if off_at is not None and time.time() >= off_at:
# делаем переход ТОЛЬКО если ещё не оффлайн
if globals().get("CURRENT_THREADS_MODE") != "offline":
logger.info("[status] switching to OFFLINE (delayed)")
stop_live_threads()
start_offline_threads(SEASON, GAME_ID)
# чтобы не повторять
globals()["OFFLINE_SWITCH_AT"] = None
try: try:
msg = results_q.get(timeout=0.5) msg = results_q.get(timeout=0.5)
except queue.Empty: except queue.Empty:
@@ -435,32 +460,43 @@ def results_consumer():
raw_ls_status_low = str(raw_ls_status).lower() raw_ls_status_low = str(raw_ls_status).lower()
finished_markers = [ finished_markers = [
"finished", "finished", "result", "resultconfirmed",
"result", "ended", "final", "game over",
"resultconfirmed",
"ended",
"final",
"game over",
] ]
# матч ЗАКОНЧЕН → гасим live и включаем offline # 1) матч ЗАКОНЧЕН → запускаем ОТСРОЧЕННЫЙ переход
if any(m in raw_ls_status_low for m in finished_markers): if any(m in raw_ls_status_low for m in finished_markers):
logger.info("[status] match finished → switch to OFFLINE") now_ts = time.time()
if ( # если ещё не назначали переход — назначим
GAME_START_DT if globals().get("OFFLINE_SWITCH_AT") is None:
and GAME_START_DT.date() == datetime.now().date() switch_at = now_ts + globals().get("OFFLINE_DELAY_SEC", 600)
): globals()["OFFLINE_SWITCH_AT"] = switch_at
globals()["STATUS"] = "finished_today"
# статус тоже обозначим, что он завершён, но ждёт
if (
GAME_START_DT
and GAME_START_DT.date() == datetime.now().date()
):
globals()["STATUS"] = "finished_wait"
else:
globals()["STATUS"] = "finished_wait"
human_time = datetime.fromtimestamp(switch_at).strftime("%H:%M:%S")
logger.info(
f"[status] match finished → will switch to OFFLINE at {human_time} "
f"(in {globals().get('OFFLINE_DELAY_SEC', 600)}s)"
)
else: else:
globals()["STATUS"] = "finished" # уже ждём — можно в debug
logger.debug("[status] match finished → OFFLINE already scheduled")
stop_live_threads() # 2) матч снова стал онлайном → СБРАСЫВАЕМ отложенный переход
start_offline_threads(SEASON, GAME_ID) elif "online" in raw_ls_status_low or "live" in raw_ls_status_low:
# если до этого стояла отложка — уберём
if globals().get("OFFLINE_SWITCH_AT") is not None:
logger.info("[status] match back to LIVE → cancel scheduled OFFLINE")
globals()["OFFLINE_SWITCH_AT"] = None
# матч СТАЛ онлайном (напр., из Scheduled → Online)
elif (
"online" in raw_ls_status_low or "live" in raw_ls_status_low
):
if globals().get("STATUS") not in ["live", "live_soon"]: if globals().get("STATUS") not in ["live", "live_soon"]:
logger.info( logger.info(
"[status] match became LIVE → switch to LIVE threads" "[status] match became LIVE → switch to LIVE threads"
@@ -469,9 +505,8 @@ def results_consumer():
start_live_threads(SEASON, GAME_ID) start_live_threads(SEASON, GAME_ID)
except Exception as e: except Exception as e:
logger.warning( logger.warning(f"results_consumer: live-status postprocess error: {e}")
f"results_consumer: live-status postprocess error: {e}"
)
else: else:
if source == "game": if source == "game":
@@ -1050,18 +1085,18 @@ async def status(request: Request):
elif status_raw in ["live_soon"]: elif status_raw in ["live_soon"]:
gs_class = "live" gs_class = "live"
gs_text = "🟢 GAME TODAY (soon)" gs_text = "🟢 GAME TODAY (soon)"
elif status_raw == "today_not_started": elif status_raw in ["finished_wait"]:
gs_class = "upcoming" gs_class = "upcoming"
gs_text = "🟡 Game today, not started" # покажем, что он ДОЖИДАЕТСЯ оффлайна
off_at = OFFLINE_SWITCH_AT
if off_at:
human = datetime.fromtimestamp(off_at).strftime("%H:%M:%S")
gs_text = f"🟡 Game finished, cooling down → OFFLINE at {human}"
else:
gs_text = "🟡 Game finished, cooling down"
elif status_raw in ["finished_today", "finished"]: elif status_raw in ["finished_today", "finished"]:
gs_class = "finished" gs_class = "finished"
gs_text = "🔴 Game finished" gs_text = "🔴 Game finished"
elif status_raw == "no_game_today":
gs_class = "unknown"
gs_text = "⚪ No game today"
else:
gs_class = "unknown"
gs_text = "⚪ UNKNOWN"
html = f""" html = f"""
<html> <html>