Spaces:
Running
Running
| """Application background scheduler.""" | |
| import logging | |
| from app.config import get_settings | |
| from app.services.drive_sync import sync_drive_pdfs_with_session | |
| logger = logging.getLogger(__name__) | |
| settings = get_settings() | |
| _scheduler = None | |
| def start_scheduler(): | |
| """Start recurring backend jobs.""" | |
| global _scheduler | |
| if _scheduler and _scheduler.running: | |
| return _scheduler | |
| try: | |
| from apscheduler.schedulers.background import BackgroundScheduler | |
| from apscheduler.triggers.interval import IntervalTrigger | |
| except ImportError: | |
| if settings.DRIVE_SYNC_ENABLED: | |
| logger.warning("Drive PDF sync enabled but APScheduler is not installed") | |
| return None | |
| _scheduler = BackgroundScheduler(timezone="UTC") | |
| if settings.DRIVE_SYNC_ENABLED: | |
| _scheduler.add_job( | |
| sync_drive_pdfs_with_session, | |
| trigger=IntervalTrigger(minutes=settings.DRIVE_SYNC_INTERVAL_MINUTES), | |
| id="drive_pdf_sync", | |
| name="Hourly Google Drive PDF sync", | |
| replace_existing=True, | |
| max_instances=1, | |
| coalesce=True, | |
| misfire_grace_time=300, | |
| ) | |
| logger.info( | |
| "Drive PDF sync scheduled every %s minutes", | |
| settings.DRIVE_SYNC_INTERVAL_MINUTES, | |
| ) | |
| else: | |
| logger.info("Drive PDF sync disabled") | |
| # Document processing recovery — every 5 minutes | |
| try: | |
| from app.services.cleanup import cleanup_stale_documents, cleanup_old_deleted_documents, cleanup_inactive_active_documents | |
| _scheduler.add_job( | |
| cleanup_stale_documents, | |
| trigger=IntervalTrigger(minutes=5), | |
| id="recover_stale_processing", | |
| name="Recover documents stuck in processing", | |
| replace_existing=True, | |
| max_instances=1, | |
| coalesce=True, | |
| misfire_grace_time=60, | |
| ) | |
| logger.info("Stale document recovery scheduled every 5 minutes") | |
| _scheduler.add_job( | |
| cleanup_old_deleted_documents, | |
| trigger=IntervalTrigger(days=1), | |
| id="cleanup_old_deleted", | |
| name="Purge old soft-deleted documents", | |
| replace_existing=True, | |
| max_instances=1, | |
| coalesce=True, | |
| misfire_grace_time=300, | |
| ) | |
| logger.info("Old deleted document cleanup scheduled daily") | |
| _scheduler.add_job( | |
| cleanup_inactive_active_documents, | |
| trigger=IntervalTrigger(days=1), | |
| id="cleanup_inactive_active", | |
| name="Purge active documents inactive beyond threshold", | |
| replace_existing=True, | |
| max_instances=1, | |
| coalesce=True, | |
| misfire_grace_time=300, | |
| ) | |
| logger.info("Inactive active document cleanup scheduled daily") | |
| except Exception as e: | |
| logger.warning("Could not schedule cleanup jobs: %s", e) | |
| _scheduler.start() | |
| return _scheduler | |
| def stop_scheduler(): | |
| """Stop recurring backend jobs.""" | |
| global _scheduler | |
| if _scheduler and _scheduler.running: | |
| _scheduler.shutdown(wait=False) | |
| logger.info("Background scheduler stopped") | |
| _scheduler = None | |