++ consolidamento funzionalità Backup

This commit is contained in:
2026-07-29 16:34:11 +02:00
parent fd15903c9c
commit 7ac454cd25
16 changed files with 585 additions and 30 deletions

View File

@@ -87,6 +87,25 @@ class CreateBackupArchive implements ShouldQueue
$stato->markCompleted($this->operationId, $risultato);
}
/**
* Chiamato da Laravel quando il job muore per cause che handle() non puo'
* intercettare: il timeout del worker (che uccide il processo), un errore
* fatale, una dipendenza non risolvibile.
*
* Senza, l'operazione resterebbe "in corso" e terrebbe occupato il posto
* unico fino alla scadenza del puntatore: un'ora in cui nessuno puo'
* avviare un backup e la pagina mostra una barra che non avanzera' mai.
*/
public function failed(?\Throwable $e): void
{
app(BackupOperationState::class)->markFailed(
$this->operationId,
$e?->getMessage() ?: 'Creazione del backup interrotta (timeout o errore del worker).'
);
@unlink(self::percorso($this->operationId));
}
public static function percorso(string $operationId): string
{
return storage_path('app/backups/' . $operationId . '.zip');

View File

@@ -150,6 +150,19 @@ class ResetApplication implements ShouldQueue
$stato->markCompleted($this->operationId, ['messaggio' => $messaggio]);
}
/**
* Vedi CreateBackupArchive::failed(): chiude l'operazione quando il job
* muore per cause che handle() non intercetta, liberando il posto unico.
*/
public function failed(?\Throwable $e): void
{
app(BackupOperationState::class)->markFailed(
$this->operationId,
($e?->getMessage() ?: 'Azzeramento interrotto (timeout o errore del worker).')
. ' Controlla lo stato dei dati prima di ritentare.'
);
}
/**
* Cancella ogni utente tranne chi ha chiesto l'azzeramento.
*

View File

@@ -14,6 +14,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Spatie\Permission\PermissionRegistrar;
/**
* Ripristina un pacchetto di backup in coda, riportando l'avanzamento fase per
@@ -82,6 +83,13 @@ class RestoreBackupArchive implements ShouldQueue
$stato->fase($this->operationId, 'Blocco degli account', 1);
$utenti = $this->richiediCambioPasswordATutti();
// L'import ricrea ruoli e assegnazioni, ma Spatie tiene in cache la
// mappa permessi-ruoli: senza questo, i processi che l'hanno gia'
// caricata continuano a decidere gli accessi con quella di prima
// del ripristino, finche' la cache non scade da sola.
app(PermissionRegistrar::class)->forgetCachedPermissions();
$stato->avanza($this->operationId, 1, 1);
} catch (\Throwable $e) {
Log::error('Ripristino del backup non riuscito.', ['exception' => $e]);
@@ -125,6 +133,27 @@ class RestoreBackupArchive implements ShouldQueue
]);
}
/**
* Vedi CreateBackupArchive::failed(): chiude l'operazione quando il job
* muore per cause che handle() non intercetta, cosi' il posto unico si
* libera subito invece di restare occupato fino alla scadenza.
*
* Qui il messaggio dice anche in che stato si e' rimasti: un ripristino
* interrotto a meta' e' l'unico caso in cui l'applicazione puo' trovarsi
* con database e file disallineati, e chi legge deve sapere che la strada
* e' rilanciare il ripristino, non ignorare l'errore.
*/
public function failed(?\Throwable $e): void
{
app(BackupOperationState::class)->markFailed(
$this->operationId,
($e?->getMessage() ?: 'Ripristino interrotto (timeout o errore del worker).')
. ' I dati possono essere rimasti a meta\': rilancia il ripristino con lo stesso pacchetto.'
);
@unlink($this->zipPath);
}
/**
* Blocca ogni account finche' non sceglie una password nuova,
* l'amministratore che sta ripristinando compreso.