fix(core): centralize async/sync bridge for APScheduler scheduled jobs
Create AsyncJobRunner — centralized bridge between APScheduler (BackgroundScheduler, sync thread pool) and async coroutines. Fixes: - P0: execute_run() called without await from APScheduler thread, causing coroutine to be silently discarded (root cause: no translation history) - P0: get_async_job_runner() deadlock when called from APScheduler thread pool without running event loop - P1: ID mismatch in disable_schedule/delete_schedule routes (job_id passed instead of schedule_id) - P1: asyncio.run() in APScheduler callbacks incompatible with running event loop - Delete unused llm_analysis/scheduler.py (not used in production) Changes: core/async_job_runner.py — new: AsyncJobRunner class core/scheduler.py — use runner.run()/run_later() translate/scheduler.py — use runner.run() for execute_run mapping_service.py — remove unused BackgroundScheduler dependencies.py — add get_async_job_runner() DI app.py — init runner in lifespan api/routes/migration.py — use runner.run() _schedule_routes.py — fix ID mismatch plugins/migration.py — use runner.run() llm_analysis/scheduler.py — delete (unused) tests: 151 new/updated tests, all passing
This commit is contained in:
@@ -61,7 +61,7 @@ from .core.database import AuthSessionLocal, init_db
|
||||
from .core.encryption_key import ensure_encryption_key
|
||||
from .core.logger import belief_scope, logger
|
||||
from .core.utils.network import NetworkError
|
||||
from .dependencies import get_scheduler_service, get_task_manager
|
||||
from .dependencies import get_async_job_runner, get_scheduler_service, get_task_manager
|
||||
from .models.auth import Role, User
|
||||
|
||||
|
||||
@@ -108,6 +108,8 @@ async def lifespan(app: FastAPI):
|
||||
_s.close()
|
||||
except Exception as _e:
|
||||
logger.warning(f"Failed to clean up stuck validation runs: {_e}")
|
||||
logger.info("⏰ Initializing AsyncJobRunner...")
|
||||
get_async_job_runner() # Initialize singleton with running event loop BEFORE scheduler starts
|
||||
logger.info("⏰ Starting scheduler...")
|
||||
scheduler = get_scheduler_service()
|
||||
scheduler.start()
|
||||
|
||||
Reference in New Issue
Block a user