markRunning($this->operationId); $state->log($this->operationId, 'Rigenerazione avviata.'); $mappe = TerritorioMappa::with('territorio')->orderBy('territorio_id')->get(); $processed = 0; $falliti = 0; foreach ($mappe as $mappa) { $territorio = $mappa->territorio; $etichetta = $territorio ? "territorio {$territorio->numero}" : "mappa #{$mappa->id}"; try { if (! $territorio) { throw new \RuntimeException('il territorio associato non esiste più'); } $renderer->render($mappa); $state->log($this->operationId, "Immagine rigenerata per {$etichetta}."); if ($this->anchePdf) { $pdfService->sostituisci($territorio, $mappa, 'rigenerazione'); $state->log($this->operationId, "PDF sostituito per {$etichetta}."); } } catch (\Throwable $e) { $falliti++; $state->log($this->operationId, "[ERRORE] {$etichetta}: {$e->getMessage()}"); } $processed++; $state->avanza($this->operationId, $processed, $falliti); } $state->log( $this->operationId, 'Rigenerazione conclusa: ' . ($processed - $falliti) . ' riuscite, ' . $falliti . ' fallite.' ); $state->markCompleted($this->operationId); } /** * Chiude l'operazione quando il job muore fuori da handle() (timeout, * worker terminato): senza, la pagina resterebbe a interrogare per sempre * uno stato "running". */ public function failed(?\Throwable $e): void { app(PiantineOperationState::class)->markFailed( $this->operationId, $e?->getMessage() ?? 'Job interrotto in modo inatteso.' ); } }