-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
On startup, RecoveryManager queries findByStatus(QUEUED) and directly enqueues tasks into the queue without checking dependencyRepo.isBlocked(). If the system crashed after tasks were saved but before DependencyHandler processed events, pipeline steps could run out of order on restart.
Root Cause
The dependencyState field is in-memory only — not persisted to the database. When RecoveryManager recovers QUEUED tasks, it has no way to know which tasks were blocked by dependencies at the time of the crash.
Affected Code
File: src/services/recovery-manager.ts
The recovery flow:
taskRepo.findByStatus('QUEUED')— finds all QUEUED tasks- Directly emits
TaskQueuedevents for each — no dependency check
Expected Behavior
Before re-enqueuing a QUEUED task, RecoveryManager should call dependencyRepo.isBlocked(taskId) to check if the task has unresolved dependencies. Blocked tasks should be skipped — they'll be unblocked when their dependencies complete via normal event flow.
Impact
Medium — the crash window between task save and dependency registration is narrow, but if hit, pipeline steps could run out of order (e.g., step 3 starts before step 1 completes).
References
- Identified during Issue refactor: add runInTransaction for atomic multi-step DB operations #81 planning (transaction atomicity refactor)
- Pre-existing issue — not introduced by refactor: add runInTransaction for atomic multi-step DB operations #81