++ Prima versione del designer piantine + Skill grafica
This commit is contained in:
152
app/Services/Piantine/PiantineOperationState.php
Normal file
152
app/Services/Piantine/PiantineOperationState.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Piantine;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/**
|
||||
* Stato della rigenerazione massiva delle piantine.
|
||||
*
|
||||
* Stessa impostazione di BackupOperationState e TerritorioPdfImportState:
|
||||
* la pagina segue il lavoro in coda interrogando questo stato, la barra si
|
||||
* muove su unità di lavoro completate davvero (territori renderizzati).
|
||||
* Un'operazione alla volta: due rigenerazioni parallele martellerebbero il
|
||||
* renderer e il tile server senza alcun beneficio.
|
||||
*/
|
||||
class PiantineOperationState
|
||||
{
|
||||
protected int $ttlSeconds = 86400;
|
||||
|
||||
private const MAX_LOG = 60;
|
||||
private const CHIAVE_CORRENTE = 'piantine-op:corrente';
|
||||
private const TTL_CORRENTE = 3600;
|
||||
|
||||
public function initialize(string $id, int $total, bool $anchePdf): array
|
||||
{
|
||||
$state = [
|
||||
'id' => $id,
|
||||
'status' => 'queued',
|
||||
'anche_pdf' => $anchePdf,
|
||||
'total' => $total,
|
||||
'processed' => 0,
|
||||
'falliti' => 0,
|
||||
'logs' => [],
|
||||
'error' => null,
|
||||
'started_at' => null,
|
||||
'finished_at' => null,
|
||||
];
|
||||
|
||||
$this->put($id, $state);
|
||||
Cache::put(self::CHIAVE_CORRENTE, $id, self::TTL_CORRENTE);
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
public function corrente(): ?string
|
||||
{
|
||||
$id = Cache::get(self::CHIAVE_CORRENTE);
|
||||
|
||||
if (! is_string($id) || $id === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stato = $this->get($id);
|
||||
|
||||
if ($stato === null || in_array($stato['status'] ?? '', ['completed', 'failed'], true)) {
|
||||
Cache::forget(self::CHIAVE_CORRENTE);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function get(string $id): ?array
|
||||
{
|
||||
return Cache::get($this->key($id));
|
||||
}
|
||||
|
||||
public function put(string $id, array $state): void
|
||||
{
|
||||
Cache::put($this->key($id), $state, $this->ttlSeconds);
|
||||
}
|
||||
|
||||
public function update(string $id, callable $callback): void
|
||||
{
|
||||
$state = $this->get($id);
|
||||
|
||||
if (! $state) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->put($id, $callback($state) ?? $state);
|
||||
}
|
||||
|
||||
public function log(string $id, string $message): void
|
||||
{
|
||||
$this->update($id, function (array $state) use ($message) {
|
||||
$state['logs'][] = '[' . now()->format('H:i:s') . '] ' . $message;
|
||||
$state['logs'] = array_slice($state['logs'], -self::MAX_LOG);
|
||||
|
||||
return $state;
|
||||
});
|
||||
}
|
||||
|
||||
public function avanza(string $id, int $processed, int $falliti): void
|
||||
{
|
||||
$this->update($id, function (array $state) use ($processed, $falliti) {
|
||||
$state['processed'] = $processed;
|
||||
$state['falliti'] = $falliti;
|
||||
|
||||
return $state;
|
||||
});
|
||||
}
|
||||
|
||||
public function markRunning(string $id): void
|
||||
{
|
||||
$this->update($id, function (array $state) {
|
||||
$state['status'] = 'running';
|
||||
$state['started_at'] ??= now()->toDateTimeString();
|
||||
|
||||
return $state;
|
||||
});
|
||||
}
|
||||
|
||||
public function markCompleted(string $id): void
|
||||
{
|
||||
$this->update($id, function (array $state) {
|
||||
$state['status'] = 'completed';
|
||||
$state['finished_at'] = now()->toDateTimeString();
|
||||
|
||||
return $state;
|
||||
});
|
||||
|
||||
$this->liberaCorrente($id);
|
||||
}
|
||||
|
||||
public function markFailed(string $id, string $error): void
|
||||
{
|
||||
$this->update($id, function (array $state) use ($error) {
|
||||
$state['status'] = 'failed';
|
||||
$state['error'] = $error;
|
||||
$state['finished_at'] = now()->toDateTimeString();
|
||||
|
||||
return $state;
|
||||
});
|
||||
|
||||
$this->log($id, 'ERRORE: ' . $error);
|
||||
$this->liberaCorrente($id);
|
||||
}
|
||||
|
||||
private function liberaCorrente(string $id): void
|
||||
{
|
||||
if (Cache::get(self::CHIAVE_CORRENTE) === $id) {
|
||||
Cache::forget(self::CHIAVE_CORRENTE);
|
||||
}
|
||||
}
|
||||
|
||||
protected function key(string $id): string
|
||||
{
|
||||
return 'piantine-op:' . $id;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user