feat(tasks): add background task scheduler for LLM expiry fallback #6

Closed
pyr0ball wants to merge 0 commits from feature/shared-task-scheduler into main
Owner

Summary

  • Adds app/tasks/runner.py wiring Kiwi to circuitforge_core.tasks.scheduler
  • Task type: expiry_llm_fallback (2.0 GB VRAM budget) — calls ExpirationPredictor when barcode/OCR expiry parsing fails
  • insert_task() is idempotent: returns (task_id, is_new) using INSERT OR IGNORE
  • Migration 006: background_tasks table + status index
  • Lifespan in app/main.py starts the scheduler and calls shutdown(timeout=10.0) + reset_scheduler() on teardown
  • ExpirationPredictor at module scope (required for patch() to intercept it in tests)

⚠️ Depends on Circuit-Forge/circuitforge-core#2 (shared task scheduler)

Test plan

  • App starts and scheduler initialises without error
  • expiry_llm_fallback task enqueues and runs via _run_expiry_llm_fallback()
  • Duplicate insert_task() calls return same task_id, is_new=False
  • Scheduler shuts down cleanly on app teardown
## Summary - Adds `app/tasks/runner.py` wiring Kiwi to `circuitforge_core.tasks.scheduler` - Task type: `expiry_llm_fallback` (2.0 GB VRAM budget) — calls `ExpirationPredictor` when barcode/OCR expiry parsing fails - `insert_task()` is idempotent: returns `(task_id, is_new)` using `INSERT OR IGNORE` - Migration 006: `background_tasks` table + status index - Lifespan in `app/main.py` starts the scheduler and calls `shutdown(timeout=10.0)` + `reset_scheduler()` on teardown - `ExpirationPredictor` at module scope (required for `patch()` to intercept it in tests) > ⚠️ **Depends on Circuit-Forge/circuitforge-core#2** (shared task scheduler) ## Test plan - [ ] App starts and scheduler initialises without error - [ ] `expiry_llm_fallback` task enqueues and runs via `_run_expiry_llm_fallback()` - [ ] Duplicate `insert_task()` calls return same `task_id`, `is_new=False` - [ ] Scheduler shuts down cleanly on app teardown
pyr0ball closed this pull request 2026-04-08 21:58:58 -07:00

Pull request closed

Sign in to join this conversation.
No description provided.