поправленны правильные переходы из live в offline матчи в тредах и статусе
This commit is contained in:
103
get_data.py
103
get_data.py
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user