100 lines
3.2 KiB
PHP
100 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Models\TerritorioMappa;
|
|
use App\Services\Piantine\PiantinaPdfService;
|
|
use App\Services\Piantine\PiantinaRenderer;
|
|
use App\Services\Piantine\PiantineOperationState;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
use Illuminate\Queue\SerializesModels;
|
|
|
|
/**
|
|
* Rigenerazione massiva delle piantine: per ogni territorio con un poligono
|
|
* disegnato rigenera l'immagine dal renderer e, a richiesta, ricompone e
|
|
* sostituisce anche il PDF (versione precedente archiviata nello storico).
|
|
*
|
|
* Un territorio che fallisce non ferma gli altri: viene contato e loggato,
|
|
* l'esito finale riepiloga quanti sono andati a buon fine.
|
|
*/
|
|
class RigeneraPiantine implements ShouldQueue
|
|
{
|
|
use Dispatchable;
|
|
use InteractsWithQueue;
|
|
use Queueable;
|
|
use SerializesModels;
|
|
|
|
public int $tries = 1;
|
|
|
|
// Rendering + PDF per decine di territori: largo ma non illimitato, per
|
|
// non lasciare il worker inchiodato se il renderer smette di rispondere.
|
|
public int $timeout = 5400;
|
|
|
|
public function __construct(
|
|
public string $operationId,
|
|
public bool $anchePdf,
|
|
) {
|
|
}
|
|
|
|
public function handle(
|
|
PiantineOperationState $state,
|
|
PiantinaRenderer $renderer,
|
|
PiantinaPdfService $pdfService,
|
|
): void {
|
|
$state->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.'
|
|
);
|
|
}
|
|
}
|