linkedid; $lockKey = "missed-call-prep-lock:{$linkedid}"; // SET NX ensures at most one worker processes each linkedid at a time. if (! Redis::set($lockKey, 1, 'EX', self::LOCK_TTL, 'NX')) { if (CompanySettings::get(SettingsHelper::S_COMPANY_CONSOLE_DEBUG_LOGS)) { Log::info("[PrepareMissedCallDataJob] Lock already held for {$linkedid} — skipping duplicate."); } return; } try { if (InboundReport::where('linkedid', $linkedid)->exists()) { if (CompanySettings::get(SettingsHelper::S_COMPANY_CONSOLE_DEBUG_LOGS)) { Log::info("[PrepareMissedCallDataJob] Report already exists for {$linkedid} — skipping."); } return; } app(MissedCallsService::class)->processSingleMissedCall($linkedid); // Run ring-detail status analysis now that the inbound_report record exists (new AnalyzeMissedCalls())->analyzeSingleCall($linkedid); } catch (\Throwable $e) { Redis::del($lockKey); if (CompanySettings::get(SettingsHelper::S_COMPANY_CONSOLE_DEBUG_LOGS)) { Log::error("[PrepareMissedCallDataJob] Failed for {$linkedid}: " . $e->getMessage()); } throw $e; } } public function failed(\Throwable $exception): void { if (CompanySettings::get(SettingsHelper::S_COMPANY_CONSOLE_DEBUG_LOGS)) { Log::error("[PrepareMissedCallDataJob] All attempts exhausted for {$this->linkedid}: " . $exception->getMessage()); } } }