diff --git a/app/Console/Commands/ScheduledJobDiagnostics.php b/app/Console/Commands/ScheduledJobDiagnostics.php index a99184cc96..d8ebcc7806 100644 --- a/app/Console/Commands/ScheduledJobDiagnostics.php +++ b/app/Console/Commands/ScheduledJobDiagnostics.php @@ -211,8 +211,8 @@ class ScheduledJobDiagnostics extends Command } $dedupKeys = [ - "server-patch-check:{$server->id}" => ServerManagerJob::patchCheckCron($server), - "sentinel-version-check:{$server->id}" => ServerManagerJob::sentinelVersionCheckCron($server), + "server-patch-check-v2:{$server->id}" => ServerManagerJob::patchCheckCron($server), + "sentinel-version-check-v2:{$server->id}" => ServerManagerJob::sentinelVersionCheckCron($server), "server-check:{$server->id}" => isCloud() ? '*/5 * * * *' : '* * * * *', "server-storage-check:{$server->id}" => data_get($server->settings, 'server_disk_usage_check_frequency', '0 23 * * *'), ]; diff --git a/app/Jobs/ServerManagerJob.php b/app/Jobs/ServerManagerJob.php index 95cb20fb1c..a8f2a50a31 100644 --- a/app/Jobs/ServerManagerJob.php +++ b/app/Jobs/ServerManagerJob.php @@ -184,7 +184,7 @@ class ServerManagerJob implements ShouldBeEncrypted, ShouldQueue // Unreachable servers are skipped: the SSH check would only fail. The connection check recovers them. if ($server->isSentinelEnabled() && ! Cache::has(Server::sentinelReportedVersionCacheKey($server->id)) - && shouldRunCronNow(self::sentinelVersionCheckCron($server), $serverTimezone, "sentinel-version-check:{$server->id}", $this->executionTime) + && shouldRunCronNow(self::sentinelVersionCheckCron($server), $serverTimezone, "sentinel-version-check-v2:{$server->id}", $this->executionTime) && $server->isFunctional() ) { CheckAndStartSentinelJob::dispatch($server); @@ -204,8 +204,10 @@ class ServerManagerJob implements ShouldBeEncrypted, ShouldQueue } } - // Dispatch ServerPatchCheckJob if due (weekly, staggered per server on Sunday) - $shouldRunPatchCheck = shouldRunCronNow(self::patchCheckCron($server), $serverTimezone, "server-patch-check:{$server->id}", $this->executionTime); + // Dispatch ServerPatchCheckJob if due (weekly, staggered per server on Sunday). + // The "-v2" keys start fresh: v4.3.23 stored its old run times under the unversioned keys, which + // would make every server run these checks at once on the first run after the upgrade. + $shouldRunPatchCheck = shouldRunCronNow(self::patchCheckCron($server), $serverTimezone, "server-patch-check-v2:{$server->id}", $this->executionTime); if ($shouldRunPatchCheck) { ServerPatchCheckJob::dispatch($server); diff --git a/tests/Feature/ScheduledJobDiagnosticsTest.php b/tests/Feature/ScheduledJobDiagnosticsTest.php index 69293c7208..34f49eeb68 100644 --- a/tests/Feature/ScheduledJobDiagnosticsTest.php +++ b/tests/Feature/ScheduledJobDiagnosticsTest.php @@ -27,8 +27,8 @@ it('does not consume the dedup keys of the server manager checks', function () { $this->artisan('scheduled:diagnostics', ['--type' => 'server-jobs'])->assertSuccessful(); expect(Cache::get("server-check:{$server->id}"))->toBeNull() - ->and(Cache::get("server-patch-check:{$server->id}"))->toBeNull() - ->and(shouldRunCronNow('0 0 * * 0', 'UTC', "server-patch-check:{$server->id}"))->toBeTrue(); + ->and(Cache::get("server-patch-check-v2:{$server->id}"))->toBeNull() + ->and(shouldRunCronNow('0 0 * * 0', 'UTC', "server-patch-check-v2:{$server->id}"))->toBeTrue(); }); it('shows the occurrence state that the scheduled job manager records', function () { diff --git a/tests/Feature/Server/ServerManagerJobStaggerTest.php b/tests/Feature/Server/ServerManagerJobStaggerTest.php index 9911c2e8fc..135caf0e84 100644 --- a/tests/Feature/Server/ServerManagerJobStaggerTest.php +++ b/tests/Feature/Server/ServerManagerJobStaggerTest.php @@ -9,6 +9,7 @@ use App\Models\Server; use App\Models\Team; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Queue; uses(RefreshDatabase::class); @@ -113,3 +114,13 @@ it('dispatches the patch check once per week at the server slot on Sunday', func runStaggerTestManagerAt($slot->copy()->addWeek()); Queue::assertPushed(ServerPatchCheckJob::class, 2); }); + +it('does not run every patch check at once after an upgrade from the old weekly schedule', function () { + $server = createStaggerTestServer($this->team); + // v4.3.23 ran the patch check for all servers on Sunday at 00:00 under this key. + Cache::put("server-patch-check:{$server->id}", Carbon::parse('2025-01-12 00:00:00', 'UTC')->toIso8601String(), 2592000); + + runStaggerTestManagerAt(Carbon::parse('2025-01-15 12:00:00', 'UTC')); + + Queue::assertNotPushed(ServerPatchCheckJob::class); +});