From a1d901dbea81ecd3ed420796432f9205a9bf4448 Mon Sep 17 00:00:00 2001 From: javara999 Date: Thu, 28 May 2026 17:32:36 +0900 Subject: [PATCH] Use same FreeGame execution path for scheduler and manual run --- logic.py | 73 ++++++-------------------------------------------------- 1 file changed, 7 insertions(+), 66 deletions(-) diff --git a/logic.py b/logic.py index d32580c..4de4bea 100644 --- a/logic.py +++ b/logic.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import threading import traceback -from datetime import datetime, timedelta import requests from flask import jsonify, render_template @@ -16,9 +15,6 @@ from .setup import P logger = P.logger package_name = P.package_name _fetch_lock = threading.Lock() -_scheduler_lock = threading.Lock() -_scheduler_stop_event = threading.Event() -_scheduler_thread = None SOURCE_LABELS = { "epic": "Epic", @@ -57,48 +53,6 @@ def _split_source_payload(results): return grouped -def _next_run_wait(interval): - now = datetime.now() - try: - from croniter import croniter - - next_run = croniter(interval, now).get_next(datetime) - return max(1, int((next_run - now).total_seconds())) - except Exception: - pass - - parts = str(interval or "").split() - if len(parts) == 5: - minute, hour = parts[0], parts[1] - if minute == "*" and hour == "*": - return 60 - if minute.startswith("*/") and hour == "*": - try: - return max(60, int(minute[2:]) * 60) - except Exception: - return 60 - if minute.isdigit() and hour.startswith("*/"): - try: - target_minute = int(minute) - step_hour = int(hour[2:]) - candidate = now.replace(second=0, microsecond=0) - for _ in range(24 * 60): - candidate += timedelta(minutes=1) - if candidate.minute == target_minute and candidate.hour % step_hour == 0: - return max(1, int((candidate - now).total_seconds())) - except Exception: - return 60 - return 60 - - -def _scheduler_loop(interval): - logger.info("FreeGame internal scheduler loop started: %s", interval) - while not _scheduler_stop_event.wait(_next_run_wait(interval)): - logger.info("FreeGame internal scheduler tick") - Logic.scheduler_function() - logger.info("FreeGame internal scheduler loop stopped") - - def _discord_send(webhook_url, games): lines = [] for game in games[:10]: @@ -199,7 +153,7 @@ class Logic(PluginModuleBase): Logic.scheduler_stop() return jsonify({"ret": "success"}) if sub == "execute_once": - threading.Thread(target=Logic.scheduler_function, daemon=True).start() + Logic.execute_once() return jsonify({"ret": "success"}) if sub == "web_list": ModelFreeGameItem.ensure_schema() @@ -214,20 +168,12 @@ class Logic(PluginModuleBase): @staticmethod def scheduler_start(): - global _scheduler_thread try: interval = ModelSetting.get("auto_interval") or "0 */2 * * *" if F.scheduler.is_include(package_name): scheduler.remove_job(package_name) - job = Job(package_name, package_name, interval, Logic.scheduler_function, "FreeGame fetch", True) + job = Job(package_name, package_name, interval, Logic.execute_once, "FreeGame fetch", True) scheduler.add_job_instance(job) - with _scheduler_lock: - if _scheduler_thread is not None and _scheduler_thread.is_alive(): - _scheduler_stop_event.set() - _scheduler_thread.join(timeout=2) - _scheduler_stop_event.clear() - _scheduler_thread = threading.Thread(target=_scheduler_loop, args=(interval,), daemon=True) - _scheduler_thread.start() logger.info("FreeGame scheduler registered: %s", interval) except Exception as e: logger.error("Exception:%s", e) @@ -235,22 +181,17 @@ class Logic(PluginModuleBase): @staticmethod def scheduler_stop(): - global _scheduler_thread try: if F.scheduler.is_include(package_name): scheduler.remove_job(package_name) except Exception as e: - logger.error("FreeGame framework scheduler stop failed: %s", e) - try: - with _scheduler_lock: - _scheduler_stop_event.set() - if _scheduler_thread is not None and _scheduler_thread.is_alive(): - _scheduler_thread.join(timeout=2) - _scheduler_thread = None - except Exception as e: - logger.error("Exception:%s", e) + logger.error("FreeGame scheduler stop failed: %s", e) logger.error(traceback.format_exc()) + @staticmethod + def execute_once(): + threading.Thread(target=Logic.scheduler_function, daemon=True).start() + @staticmethod def scheduler_function(): if not _fetch_lock.acquire(blocking=False):