Title#
feat: implement BullMQ job queue driver behind JOB_QUEUE_DRIVER config flag
Problem#
The job queue is backed by SQLite, which limits scalability and reliability. AW-11 introduces a BullMQ/Redis-backed implementation that can be switched in at runtime without breaking the existing SQLite path.
Task / Link#
Closes #457
Changes#
- Add
JOB_QUEUE_DRIVERJoi validation toconfig.schema.ts(valid:sqlite|bullmq, default:sqlite) - Create
BullMQJobQueueimplementing theJobQueueinterface using BullMQQueue+Worker - Lazy Redis connection: Queue and Worker are only instantiated when first used, so
driver=sqlitenever opens a Redis connection - Per-issue concurrency control via in-memory
activeIssuesSet; BullMQconcurrency: 1ensures sequential processing - Update
QueueModulefactory provider to selectBullMQJobQueueorSqliteJobQueuebased onJOB_QUEUE_DRIVER - Export
BullMQJobQueuefrom the queue index
Notes#
BullModule.forRootAsyncis NOT added toQueueModule—BullMQJobQueuemanages its own IORedis connections directly, matching the lazy-init design and avoiding module-level conflicts withInvokeModule. This remains a follow-up for AW-3 (#439).- Both queue implementations are registered as providers; lazy init prevents Redis connections when using the SQLite driver.
Testing#
- 13 new unit tests in
bullmq-job-queue.spec.tscovering: enqueue, onJob/worker init, per-issue dedup, error handling, andonModuleDestroycleanup - Full test suite: 824 tests pass
- Lint: zero warnings