Fix: Prevent ServerStorageCheckJob duplication when Sentinel is active

When Sentinel is enabled and in sync, ServerStorageCheckJob was being
dispatched from two locations causing unnecessary duplication:
1. PushServerUpdateJob (every ~30s with real-time filesystem data)
2. ServerManagerJob (scheduled cron check via SSH)

This commit modifies ServerManagerJob to only dispatch ServerStorageCheckJob
when Sentinel is out of sync or disabled. When Sentinel is active and in sync,
PushServerUpdateJob provides real-time storage data, making the scheduled SSH
check redundant.

Benefits:
- Eliminates duplicate storage checks when Sentinel is working
- Reduces unnecessary SSH overhead
- Storage checks still run as fallback when Sentinel fails
- Maintains scheduled checks for servers without Sentinel

Updated tests to reflect new behavior:
- Storage check NOT dispatched when Sentinel is in sync
- Storage check dispatched when Sentinel is out of sync or disabled
- All timezone and frequency tests updated accordingly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai 2025-12-03 10:05:10 +01:00
parent c982d58eee
commit 56a0143a25
2 changed files with 23 additions and 22 deletions

View file

@ -139,15 +139,18 @@ private function processServerTasks(Server $server): void
});
}
// Dispatch ServerStorageCheckJob if due (independent of Sentinel status)
$serverDiskUsageCheckFrequency = data_get($server->settings, 'server_disk_usage_check_frequency', '0 23 * * *');
if (isset(VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency])) {
$serverDiskUsageCheckFrequency = VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency];
}
$shouldRunStorageCheck = $this->shouldRunNow($serverDiskUsageCheckFrequency, $serverTimezone);
// Dispatch ServerStorageCheckJob if due (only when Sentinel is out of sync or disabled)
// When Sentinel is active, PushServerUpdateJob handles storage checks with real-time data
if ($sentinelOutOfSync) {
$serverDiskUsageCheckFrequency = data_get($server->settings, 'server_disk_usage_check_frequency', '0 23 * * *');
if (isset(VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency])) {
$serverDiskUsageCheckFrequency = VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency];
}
$shouldRunStorageCheck = $this->shouldRunNow($serverDiskUsageCheckFrequency, $serverTimezone);
if ($shouldRunStorageCheck) {
ServerStorageCheckJob::dispatch($server);
if ($shouldRunStorageCheck) {
ServerStorageCheckJob::dispatch($server);
}
}
// Dispatch ServerPatchCheckJob if due (weekly)

View file

@ -19,7 +19,7 @@
Carbon::setTestNow();
});
it('dispatches storage check when sentinel is in sync', function () {
it('does not dispatch storage check when sentinel is in sync', function () {
// Given: A server with Sentinel recently updated (in sync)
$team = Team::factory()->create();
$server = Server::factory()->create([
@ -37,10 +37,8 @@
$job = new ServerManagerJob;
$job->handle();
// Then: ServerStorageCheckJob should be dispatched
Queue::assertPushed(ServerStorageCheckJob::class, function ($job) use ($server) {
return $job->server->id === $server->id;
});
// Then: ServerStorageCheckJob should NOT be dispatched (Sentinel handles it via PushServerUpdateJob)
Queue::assertNotPushed(ServerStorageCheckJob::class);
});
it('dispatches storage check when sentinel is out of sync', function () {
@ -93,12 +91,12 @@
});
});
it('respects custom hourly storage check frequency', function () {
// Given: A server with hourly storage check frequency
it('respects custom hourly storage check frequency when sentinel is out of sync', function () {
// Given: A server with hourly storage check frequency and Sentinel out of sync
$team = Team::factory()->create();
$server = Server::factory()->create([
'team_id' => $team->id,
'sentinel_updated_at' => now(),
'sentinel_updated_at' => now()->subMinutes(10),
]);
$server->settings->update([
@ -117,12 +115,12 @@
});
});
it('handles VALID_CRON_STRINGS mapping correctly', function () {
// Given: A server with 'hourly' string (should be converted to '0 * * * *')
it('handles VALID_CRON_STRINGS mapping correctly when sentinel is out of sync', function () {
// Given: A server with 'hourly' string (should be converted to '0 * * * *') and Sentinel out of sync
$team = Team::factory()->create();
$server = Server::factory()->create([
'team_id' => $team->id,
'sentinel_updated_at' => now(),
'sentinel_updated_at' => now()->subMinutes(10),
]);
$server->settings->update([
@ -141,12 +139,12 @@
});
});
it('respects server timezone for storage checks', function () {
// Given: A server in America/New_York timezone (UTC-5) configured for 11 PM local time
it('respects server timezone for storage checks when sentinel is out of sync', function () {
// Given: A server in America/New_York timezone (UTC-5) configured for 11 PM local time and Sentinel out of sync
$team = Team::factory()->create();
$server = Server::factory()->create([
'team_id' => $team->id,
'sentinel_updated_at' => now(),
'sentinel_updated_at' => now()->subMinutes(10),
]);
$server->settings->update([