This commit is contained in:
84
main.py
Normal file
84
main.py
Normal file
@ -0,0 +1,84 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi.concurrency import asynccontextmanager
|
||||
from config.settings import settings
|
||||
from utils.logger import logger
|
||||
from scheduler.scheduler import scheduler
|
||||
import scheduler.jobs as jobs
|
||||
from config.app import create_app
|
||||
|
||||
"""
|
||||
启动方式:
|
||||
python -m uvicorn main:app --reload
|
||||
|
||||
说明:
|
||||
- 使用 FastAPI lifespan 管理 APScheduler 生命周期(替代已废弃的 on_event)
|
||||
- 避免 Uvicorn reload 模式下调度器重复启动
|
||||
- 所有 Job 在应用启动时统一注册
|
||||
"""
|
||||
|
||||
|
||||
def _add_jobs():
|
||||
"""
|
||||
注册所有定时任务。
|
||||
|
||||
注意:
|
||||
- 增加重复检查,避免 reload 或多进程导致重复添加。
|
||||
- replace_existing=True 保证任务更新时无需手动删除。
|
||||
"""
|
||||
if not scheduler.get_job("heartbeat-job"):
|
||||
scheduler.add_job(
|
||||
jobs.job_heartbeat,
|
||||
trigger="interval",
|
||||
seconds=10,
|
||||
id="heartbeat-job",
|
||||
replace_existing=True,
|
||||
)
|
||||
logger.info("Job 'heartbeat-job' registered.")
|
||||
else:
|
||||
logger.info("Job 'heartbeat-job' already exists. Skipped.")
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""
|
||||
FastAPI 应用生命周期管理。
|
||||
|
||||
startup:
|
||||
- 注册定时任务
|
||||
- 启动 APScheduler(避免 reload 环境下重复启动)
|
||||
|
||||
shutdown:
|
||||
- 安全关闭 APScheduler
|
||||
|
||||
yield:
|
||||
- 让 FastAPI 在此期间正常运行
|
||||
"""
|
||||
logger.info("==== Lifespan: startup ====")
|
||||
|
||||
# 防止 Uvicorn reload 启动两个进程导致重复启动 scheduler
|
||||
if scheduler.running:
|
||||
logger.warning("Scheduler already running. Skip start.")
|
||||
else:
|
||||
_add_jobs()
|
||||
|
||||
try:
|
||||
scheduler.start()
|
||||
logger.info("APScheduler started.")
|
||||
except Exception:
|
||||
logger.exception("Failed to start APScheduler:")
|
||||
raise
|
||||
|
||||
yield # ---- 应用运行中 ----
|
||||
|
||||
logger.info("==== Lifespan: shutdown ====")
|
||||
|
||||
# 仅在 scheduler 正常运行时关闭
|
||||
if scheduler.running:
|
||||
scheduler.shutdown(wait=False)
|
||||
logger.info("APScheduler stopped.")
|
||||
else:
|
||||
logger.info("Scheduler was not running. Skip shutdown.")
|
||||
|
||||
|
||||
# 创建 FastAPI 应用(注入 lifespan 管理逻辑)
|
||||
app = create_app(lifespan=lifespan)
|
||||
Reference in New Issue
Block a user