import logging from fastapi import APIRouter, HTTPException from concurrent.futures import ThreadPoolExecutor from app.schemas.response_template import ResponseModel from app.service.recommendation_system.precompute import run_precompute logger = logging.getLogger() router = APIRouter() # 使用线程池执行器来运行长时间任务 executor = ThreadPoolExecutor(max_workers=1) # 用于跟踪任务状态 task_status = {"running": False} def run_precompute_task(): """在后台线程中运行预计算任务""" try: task_status["running"] = True logger.info("开始执行预计算任务...") run_precompute() task_status["running"] = False logger.info("预计算任务完成") except Exception as e: task_status["running"] = False logger.error(f"预计算任务失败: {e}", exc_info=True) raise @router.post("/precompute", response_model=ResponseModel) async def precompute(): """ 运行预计算任务 该接口会异步执行预计算任务,包括: 1. 优化数据库表结构 2. 历史数据迁移 3. 初始用户偏好向量生成 任务在后台运行。 """ try: # 检查是否有任务正在运行 if task_status["running"]: raise HTTPException( status_code=409, detail="已有预计算任务正在运行,请等待完成后再试" ) # 在后台线程中执行任务 executor.submit(run_precompute_task) return ResponseModel( code=200, msg="预计算任务已启动,正在后台执行", data={ "status": "started", "tasks": [ "优化数据库表结构", "历史数据迁移", "初始用户偏好向量生成" ] } ) except HTTPException: raise except Exception as e: logger.error(f"启动预计算任务失败: {e}", exc_info=True) raise HTTPException(status_code=500, detail=f"启动预计算任务失败: {str(e)}") @router.get("/precompute/status", response_model=ResponseModel) async def get_precompute_status(): """ 获取预计算任务状态 """ return ResponseModel( code=200, msg="OK", data={ "running": task_status["running"] } )