| |
| """ |
| 缓存清理模块。 |
| 使用 APScheduler 设置后台定时任务,定期清理过期和无效的缓存。 |
| """ |
|
|
| import logging |
| from apscheduler.schedulers.asyncio import AsyncIOScheduler |
| from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession |
| from sqlalchemy.orm import sessionmaker |
|
|
| from app.core.database.utils import DATABASE_URL |
| from app.core.cache.manager import CacheManager |
|
|
| logger = logging.getLogger(__name__) |
|
|
| |
| |
| |
| async_engine = create_async_engine(DATABASE_URL, echo=False) |
| AsyncSessionFactory = sessionmaker( |
| bind=async_engine, |
| class_=AsyncSession, |
| expire_on_commit=False |
| ) |
|
|
| async def cleanup_expired_cache(): |
| """ |
| 异步后台任务:清理数据库中过期的缓存元数据和可能存在的无效缓存条目。 |
| 此函数由 APScheduler 定期调用。 |
| 它会自行创建和管理 AsyncSession。 |
| """ |
| logger.info("开始执行缓存清理任务...") |
| |
| async with AsyncSessionFactory() as session: |
| try: |
| |
| cache_manager_instance = CacheManager() |
|
|
| |
| logger.info("正在调用 cache_manager_instance.cleanup_expired_caches...") |
| await cache_manager_instance.cleanup_expired_caches(session) |
|
|
| |
| logger.info("正在调用 cache_manager_instance.cleanup_invalid_caches...") |
| await cache_manager_instance.cleanup_invalid_caches(session) |
|
|
| await session.commit() |
| logger.info(f"缓存清理任务成功完成。") |
|
|
| except Exception as e: |
| await session.rollback() |
| logger.error(f"缓存清理任务执行失败: {e}", exc_info=True) |
| finally: |
| |
| logger.info("缓存清理任务执行结束。") |
| |
|
|
| def start_cache_cleanup_scheduler(): |
| """ |
| 启动一个 APScheduler 调度器,用于定期执行缓存清理任务。 |
| 清理任务将自行管理数据库会话。 |
| |
| Returns: |
| AsyncIOScheduler: 已启动的调度器实例。 |
| """ |
| scheduler = AsyncIOScheduler() |
| |
| |
| |
| |
| |
| scheduler.add_job(cleanup_expired_cache, 'interval', hours=1) |
| scheduler.start() |
| logger.info("缓存清理调度器已启动,每小时执行一次。") |
| return scheduler |
|
|
| |
| if __name__ == "__main__": |
| |
| |
| import asyncio |
| |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
|
|
|
|
| async def main(): |
| """异步主函数,用于测试""" |
| |
| |
| |
| |
|
|
| |
| scheduler = start_cache_cleanup_scheduler() |
| |
| try: |
| while True: |
| await asyncio.sleep(3600) |
| except asyncio.CancelledError: |
| logger.info("主任务被取消。") |
| finally: |
| |
| if scheduler and scheduler.running: |
| scheduler.shutdown() |
| logger.info("缓存清理调度器已关闭。") |
|
|
| try: |
| |
| asyncio.run(main()) |
| except (KeyboardInterrupt, SystemExit): |
| logger.info("缓存清理测试程序退出。") |
|
|