Offline-tolerant music-video merge
The merge no longer refuses when NAS is unreachable. DB changes always run; per-side file operations are best-effort. When the NAS rename can't happen it's recorded in a new pending_nas_moves table, and nas:auto-sync drains the queue (rename + best-effort parent prune) once NAS is back, retaining attempts/last_error on failure. Also plugs missing isEnabled() guards on renameNasPath and deleteFolder so the merge cleanup path can't hang on smbclient timeouts. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
fcb752dd76
commit
847020fd02
4 files changed
+101
-12
No files matched your search
@@ -7,6 +7,7 @@ use App\Models\User;
|
||||
use App\Models\Video;
|
||||
use App\Services\NasSyncService;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class NasAutoSync extends Command
|
||||
{
|
||||
@@ -19,6 +20,39 @@ class NasAutoSync extends Command
|
||||
return 0; // NAS down or disabled — nothing to do
|
||||
}
|
||||
|
||||
// Drain queued NAS file/folder moves recorded while NAS was down
|
||||
// (e.g. music-video merges). Best-effort per row; failures stay
|
||||
// in the table with attempts/last_error for later retries.
|
||||
$drained = 0; $failed = 0;
|
||||
DB::table('pending_nas_moves')->orderBy('id')->get()->each(
|
||||
function ($row) use ($nas, &$drained, &$failed) {
|
||||
try {
|
||||
$nas->renameNasPath($row->from_path, $row->to_path);
|
||||
// Best-effort prune of the now-empty source parent
|
||||
// (e.g. the source video folder after all its track
|
||||
// subfolders were adopted by the target).
|
||||
$parent = dirname($row->from_path);
|
||||
if ($parent && $parent !== '.') {
|
||||
$nas->deleteFile("{$parent}/meta.json");
|
||||
$nas->deleteFolder($parent);
|
||||
}
|
||||
DB::table('pending_nas_moves')->where('id', $row->id)->delete();
|
||||
$drained++;
|
||||
} catch (\Throwable $e) {
|
||||
DB::table('pending_nas_moves')->where('id', $row->id)->update([
|
||||
'attempts' => (int) $row->attempts + 1,
|
||||
'last_attempt_at' => now(),
|
||||
'last_error' => mb_substr($e->getMessage(), 0, 500),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
$failed++;
|
||||
}
|
||||
}
|
||||
);
|
||||
if ($drained || $failed) {
|
||||
$this->info("Drained {$drained} pending NAS move(s)" . ($failed ? " (${failed} failed)" : ''));
|
||||
}
|
||||
|
||||
// Videos whose file OR thumbnail/slides are still on local disk
|
||||
$synced = 0;
|
||||
Video::with(['user', 'slides'])
|
||||
|
||||
Reference in new issue
Block a user