background_tasks.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. """
  2. 后台定时任务管理 - 管理端专用
  3. 密钥过期检查与自动生成已拆至独立工程 api-key-tasks,此处仅保留配置刷新等任务。
  4. """
  5. import asyncio
  6. from typing import List
  7. from contextlib import asynccontextmanager
  8. from app.core.logger import logger
  9. from app.core.config_cache import config_cache
  10. from app.models.system_config import SystemConfig
  11. class BackgroundTaskManager:
  12. """后台任务管理器(不含密钥定时生成,由 api-key-tasks 独立进程负责)"""
  13. def __init__(self):
  14. self.tasks: List[asyncio.Task] = []
  15. self.running = False
  16. async def start_all_tasks(self):
  17. """启动所有后台任务"""
  18. if self.running:
  19. logger.warning("后台任务已在运行")
  20. return
  21. self.running = True
  22. logger.info("启动后台定时任务...")
  23. # 加载配置并设置刷新间隔
  24. config_cache.load_configs()
  25. refresh_interval = SystemConfig.get_config_value('admin_config_refresh_interval_seconds', 60)
  26. config_cache.set_refresh_interval(refresh_interval)
  27. logger.info(f"配置刷新间隔: {refresh_interval} 秒")
  28. # 仅启动配置刷新任务;密钥过期检查由 api-key-tasks 工程独立运行
  29. self.tasks = [
  30. asyncio.create_task(self._config_refresh_task()),
  31. ]
  32. logger.info(f"已启动 {len(self.tasks)} 个后台任务")
  33. async def stop_all_tasks(self):
  34. """停止所有后台任务"""
  35. if not self.running:
  36. logger.warning("后台任务未运行")
  37. return
  38. logger.info("停止后台定时任务...")
  39. self.running = False
  40. for task in self.tasks:
  41. if not task.done():
  42. task.cancel()
  43. try:
  44. await asyncio.gather(*self.tasks, return_exceptions=True)
  45. except asyncio.CancelledError:
  46. pass
  47. self.tasks.clear()
  48. logger.info("后台定时任务已停止")
  49. async def _config_refresh_task(self):
  50. """配置刷新任务 - 定时从数据库刷新配置缓存"""
  51. refresh_interval = config_cache.get_refresh_interval()
  52. logger.info(f"启动配置刷新任务 (刷新间隔: {refresh_interval}秒)")
  53. while self.running:
  54. try:
  55. success = config_cache.refresh()
  56. if success:
  57. logger.debug(f"配置刷新成功,上次刷新时间: {config_cache.get_last_refresh_time()}")
  58. else:
  59. logger.warning("配置刷新失败")
  60. except Exception as e:
  61. logger.exception("配置刷新任务异常")
  62. # 动态获取刷新间隔(支持运行时修改)
  63. current_interval = config_cache.get_refresh_interval()
  64. await asyncio.sleep(current_interval)
  65. # 全局后台任务管理器实例
  66. background_task_manager = BackgroundTaskManager()
  67. @asynccontextmanager
  68. async def lifespan_manager(app):
  69. """FastAPI lifespan 事件管理器"""
  70. logger.info("应用启动,开始初始化后台任务...")
  71. await background_task_manager.start_all_tasks()
  72. yield
  73. logger.info("应用关闭,开始清理后台任务...")
  74. await background_task_manager.stop_all_tasks()
  75. # 便捷函数
  76. async def start_background_tasks():
  77. """启动后台任务(手动调用)"""
  78. await background_task_manager.start_all_tasks()
  79. async def stop_background_tasks():
  80. """停止后台任务(手动调用)"""
  81. await background_task_manager.stop_all_tasks()
  82. def get_task_manager() -> BackgroundTaskManager:
  83. """获取后台任务管理器实例"""
  84. return background_task_manager