Release the locks of a killed restore when it runs again; legacy test without empty folders
A killed restore left its leases for up to two hours, so the first backup of the recovered server was refused. A backup from before 1.0.3 records no empty folders: the test now expects that.
This commit is contained in:
@@ -79,7 +79,7 @@ final class BackupService {
|
||||
try {
|
||||
return $this->leases->with(PruneService::lockKey($target), LeaseService::EXCLUSIVE, 60, fn () => $this->createRun($target, $label));
|
||||
} catch (LockedException) {
|
||||
throw new \RuntimeException('A cleanup or another start for ' . $target->getName() . ' is running; try again later');
|
||||
throw new \RuntimeException('A cleanup, a restore or another start for ' . $target->getName() . ' is running, or one was stopped by force (that clears by itself within two hours); try again later');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,15 @@ final class LeaseService {
|
||||
$qb->executeStatement();
|
||||
}
|
||||
|
||||
/** Remove the shared leases on $name, for a caller that knows their holders were stopped. */
|
||||
public function dropShared(string $name): void {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->delete('ngb_leases')
|
||||
->where($qb->expr()->eq('name', $qb->createNamedParameter($name)))
|
||||
->andWhere($qb->expr()->eq('mode', $qb->createNamedParameter(self::SHARED)));
|
||||
$qb->executeStatement();
|
||||
}
|
||||
|
||||
/** Wraps $refresh so calling it often (per file, per row batch) only touches the database every $seconds. */
|
||||
public static function throttled(callable $refresh, int $seconds = 60): \Closure {
|
||||
$last = time();
|
||||
|
||||
@@ -151,6 +151,12 @@ final class RestoreFullService {
|
||||
// The database cannot go into this installation; the files can.
|
||||
$check['dbUnreadable'] = 'the database cannot be restored here: ' . $this->describeBlockers($check);
|
||||
}
|
||||
if ($interrupted) {
|
||||
// A restore that was killed leaves its leases, for up to two hours: they would keep
|
||||
// the first backup of the recovered server waiting after this restore completes.
|
||||
// In maintenance mode, on a partly restored instance, nothing else reads the location.
|
||||
$this->leases->dropShared(PruneService::lockKey($target));
|
||||
}
|
||||
$appConfig->setValueInt(\OCA\NgBackup\AppInfo\Application::APP_ID, self::INTERRUPTED_KEY, time());
|
||||
$result = $this->restoreInMaintenance($target, $snapshotId, $skipMissingTables, $check, $salvage);
|
||||
$appConfig->deleteKey(\OCA\NgBackup\AppInfo\Application::APP_ID, self::INTERRUPTED_KEY);
|
||||
|
||||
Reference in New Issue
Block a user