فهرست منبع

feat: 定时任务每天8点钟开启

jihuaqiang 20 ساعت پیش
والد
کامیت
58428f0281
1فایلهای تغییر یافته به همراه25 افزوده شده و 4 حذف شده
  1. 25 4
      examples/content_finder/server.py

+ 25 - 4
examples/content_finder/server.py

@@ -3,8 +3,9 @@
 
 提供:
 1. API 接口:POST /api/tasks - 触发内容寻找任务
-2. 定时调度:启动后先恢复 demand_find_task 中 status=执行中 的任务;之后每 2 分钟轮询一次,
-   若当前无任务在执行,则从 demand_content 取当天(dt=YYYYMMDD)、未建任务记录且 score 最高的一条执行(不区分品类)
+2. 定时调度:启动后先恢复 demand_find_task 中 status=执行中 的任务;之后按间隔轮询;
+   若当前无任务在执行,则从 demand_content 取当天(dt=YYYYMMDD)、未建任务记录且 score 最高的一条执行(不区分品类)。
+   本文件常量 SCHEDULE_DISPATCH_NOT_BEFORE_HOUR:仅在该本地时刻(SCHEDULER_TIMEZONE)及之后才派发;与按 UTC 计日的上游日限额对齐时常用 8(北京 08:00 = UTC 换日)。
 3. 并发控制:限制最大并发任务数;定时侧若已有任务在执行则跳过本次轮询
 4. 单次寻找任务最长执行 25 分钟,超时记为失败并回写 demand_find_task
 """
@@ -75,6 +76,10 @@ task_semaphore = asyncio.Semaphore(MAX_CONCURRENT_TASKS)
 SCHEDULE_DISPATCH_INTERVAL_SECONDS = int(os.getenv("SCHEDULE_DISPATCH_INTERVAL_SECONDS", "30"))
 TASK_TIMEOUT_SECONDS = int(os.getenv("SCHEDULE_TASK_TIMEOUT_SECONDS", "1500"))
 
+# 定时派发最早本地整点(0-23,含该小时起至当日结束;SCHEDULER_TIMEZONE)。None=不限制。
+# 上游按 UTC 计日(如 OpenRouter 日限额)时与 UTC 换日对齐可改为 8。
+SCHEDULE_DISPATCH_NOT_BEFORE_HOUR: Optional[int] = 8
+
 # 统计信息
 stats = {
     "total_tasks": 0,
@@ -199,6 +204,17 @@ async def scheduled_tick():
     按 SCHEDULE_DISPATCH_INTERVAL_SECONDS 派发:若当前并发有空槽,则从 demand_content 取
     当天(dt=今日)、尚未出现在 demand_find_task 中且 score 最高的一条需求并执行。
     """
+    if SCHEDULE_DISPATCH_NOT_BEFORE_HOUR is not None:
+        now = datetime.now(SCHEDULER_TZ)
+        if now.hour < SCHEDULE_DISPATCH_NOT_BEFORE_HOUR:
+            logger.info(
+                "定时任务跳过:未到本地派发窗口(需 %02d:00 %s 及之后,当前 %s)",
+                SCHEDULE_DISPATCH_NOT_BEFORE_HOUR,
+                SCHEDULER_TIMEZONE,
+                now.strftime("%H:%M"),
+            )
+            return
+
     logger.info("定时任务触发(scheduled_tick)")
 
     # demand_task_oprate:最新一条 is_open=0 时关闭定时派发;无记录时默认继续(兼容未配置)
@@ -445,9 +461,14 @@ async def startup():
     logger.info("内容寻找服务启动中...")
     logger.info(f"最大并发任务数: {MAX_CONCURRENT_TASKS}")
     logger.info(f"定时器时区: {SCHEDULER_TIMEZONE}")
+    window_desc = (
+        f";本地派发不早于 {SCHEDULE_DISPATCH_NOT_BEFORE_HOUR:02d}:00({SCHEDULER_TIMEZONE})"
+        if SCHEDULE_DISPATCH_NOT_BEFORE_HOUR is not None
+        else ""
+    )
     logger.info(
-        f"定时策略:每 {SCHEDULE_DISPATCH_INTERVAL_SECONDS} 秒尝试派发 1 条(有并发空槽才派发);"
-        f"单次任务超时 {TASK_TIMEOUT_SECONDS}s"
+        f"定时策略:每 {SCHEDULE_DISPATCH_INTERVAL_SECONDS} 秒尝试派发 1 条(有并发空槽才派发)"
+        f"{window_desc};单次任务超时 {TASK_TIMEOUT_SECONDS}s"
     )
 
     asyncio.create_task(run_startup_resume())