Class: DailyFocusOrphanReaperWorker
- Inherits:
-
Object
- Object
- DailyFocusOrphanReaperWorker
- Includes:
- Sidekiq::Job
- Defined in:
- app/workers/daily_focus_orphan_reaper_worker.rb
Overview
Recovers Daily Focus briefings orphaned in processing.
When a DailyFocusAnalysisRepWorker is killed mid-run (deploy restart, OOM,
hard kill), the briefing is stranded: Sidekiq::Shutdown is an Interrupt,
not a StandardError, so the worker's rescue never advances the status to
failed, and the ensure releases the column lock — leaving
daily_focus_status='processing' with no worker on it. AssistantLockCleanupWorker
clears the stale lock but never touches the status, and the next scheduled run
skips the rep because a briefing already exists. The rep sits in "Processing"
forever (2026-06-16 10:05 UTC deploy stranded 3 reps).
This sweep re-enqueues DailyFocusAnalysisRepWorker for each orphan, preserving
its covered reps. The rep worker reclaims the orphan and regenerates in place
(under a per-rep advisory lock, so this can't create duplicates even if it
races a Sidekiq retry).
Runs every 10 minutes on weekday business hours via sidekiq-scheduler.
Instance Method Summary collapse
Instance Method Details
#perform ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'app/workers/daily_focus_orphan_reaper_worker.rb', line 25 def perform cutoff = DailyFocus::ORPHAN_AFTER.ago recovered = 0 AssistantConversation .daily_focus_processing(Date.current) .where(updated_at: ...cutoff) .find_each do |conversation| # Belt-and-suspenders: skip anything a live worker is still on (the # updated_at filter already excludes recent activity, but a fresh column # lock means hands off regardless). next if DailyFocus.briefing_live?(conversation) target_id = conversation.daily_focus_target_employee_id next unless target_id DailyFocusAnalysisRepWorker.perform_async( target_id, nil, Array(conversation.daily_focus_covered_employee_ids) ) recovered += 1 end Rails.logger.info("[DailyFocusOrphanReaperWorker] Re-enqueued #{recovered} orphaned daily-focus briefing(s)") if recovered.positive? end |