checkUlid, 75)->block(1, function () use ($registry, $persister, $audit) { $c = SerpCheck::where('ulid', $this->checkUlid)->firstOrFail(); if (in_array($c->status, [SerpCheckStatus::Completed, SerpCheckStatus::Failed], true)) { return; }if ($c->status !== SerpCheckStatus::Running || ! $c->provider_reference) { $c->fail('provider_task_missing', 'SERP kontrolü tamamlanamadı.'); return; }$attempts = $c->provider_poll_attempts + 1; $c->forceFill(['provider_poll_attempts' => $attempts, 'provider_last_polled_at' => now(), 'provider_next_poll_at' => null])->save(); if ($attempts > (int) config('serp.dataforseo.poll_max_attempts') || $c->provider_task_posted_at?->lt(now()->subMinutes((int) config('serp.dataforseo.max_task_age_minutes')))) { $c->fail('provider_task_expired', 'SERP kontrolü zamanında tamamlanamadı.'); $audit->record('poll_exhausted', ['check_ulid' => $c->ulid, 'attempt' => $attempts, 'error_category' => 'poll_exhausted']); return; }try { $p = $registry->resolve($c->provider); if (! $p instanceof AsyncSerpProvider) { throw new UnexpectedProviderResponseException('Provider does not support standard mode.'); }$result = $p->collect($c->provider_reference, 10); $c->forceFill(['provider_status_code' => $result->statusCode])->save(); if (! $result->ready) { $delay = (int) config('serp.dataforseo.poll_interval') * min($attempts, 4); $at = now()->addSeconds($delay); $c->forceFill(['provider_next_poll_at' => $at])->save(); self::dispatch($c->ulid)->delay($at)->onQueue(config('serp.queue')); $audit->record('poll_not_ready', ['check_ulid' => $c->ulid, 'attempt' => $attempts]); return; }$persister->complete($c, $result->response, ['provider_cost' => $c->provider_cost ?? $result->cost, 'provider_cost_currency' => $result->currency, 'provider_status_code' => $result->statusCode, 'provider_next_poll_at' => null]); $audit->record('poll_completed', ['check_ulid' => $c->ulid, 'attempt' => $attempts, 'result_count' => count($result->response->results)]); } catch (SerpProviderException $e) { $audit->record('poll_failed', ['check_ulid' => $c->ulid, 'attempt' => $attempts, 'error_category' => $e->safeCode()]); if ($e->retryable()) { throw $e; }$c->fail($e->safeCode(), $e->safeMessage()); } catch (Throwable) { $c->fail('unexpected_error', 'SERP kontrolü tamamlanamadı.'); } }); } public function failed(?Throwable $e): void { $c = SerpCheck::where('ulid', $this->checkUlid)->first(); if ($c && $e instanceof SerpProviderException) { $c->fail($e->safeCode(), $e->safeMessage()); } elseif ($c) { $c->fail('job_failed', 'SERP kontrolü tamamlanamadı.'); } } public function tags(): array { return ['serp-check:'.$this->checkUlid, 'serp-mode:standard-poll']; } }