From 8564741d38eee133fb315e123ffe16b9f6a804c4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 5 Oct 2026 21:24:32 +0200 Subject: [PATCH] fix(notifications): send a disk usage alert again after usage drops The high disk usage throttle stayed for 24 hours after usage dropped, so a new spike in that time sent no alert. - Release the throttle when disk usage is at or below the threshold --- app/Jobs/ServerStorageCheckJob.php | 4 ++++ ...erStorageCheckNotificationIntervalTest.php | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/app/Jobs/ServerStorageCheckJob.php b/app/Jobs/ServerStorageCheckJob.php index a457207951..1e1b2c3c2a 100644 --- a/app/Jobs/ServerStorageCheckJob.php +++ b/app/Jobs/ServerStorageCheckJob.php @@ -2,6 +2,7 @@ namespace App\Jobs; +use App\Models\NotificationThrottle; use App\Models\Server; use App\Notifications\Server\HighDiskUsage; use Illuminate\Bus\Queueable; @@ -59,6 +60,9 @@ class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue, Silenced } if ($this->percentage > $serverDiskUsageNotificationThreshold) { $team->notify(new HighDiskUsage($this->server, $this->percentage, $serverDiskUsageNotificationThreshold)); + } else { + // Usage recovered: the next spike should alert again instead of waiting for the interval. + NotificationThrottle::release($this->server, HighDiskUsage::class); } } catch (\Throwable $e) { return handleError($e); diff --git a/tests/Feature/Server/ServerStorageCheckNotificationIntervalTest.php b/tests/Feature/Server/ServerStorageCheckNotificationIntervalTest.php index ff0caf1a98..d4e9563396 100644 --- a/tests/Feature/Server/ServerStorageCheckNotificationIntervalTest.php +++ b/tests/Feature/Server/ServerStorageCheckNotificationIntervalTest.php @@ -67,6 +67,25 @@ it('sends one high disk usage notification per configured interval', function () Notification::assertSentToTimes($server->team, HighDiskUsage::class, 2); }); +it('notifies again on a new spike after disk usage recovered within the interval', function () { + $server = diskUsageIntervalServer(intervalHours: 24); + + runDiskUsageCheck($server, 93); + Notification::assertSentToTimes($server->team, HighDiskUsage::class, 1); + + Carbon::setTestNow(now()->addMinutes(10)); + runDiskUsageCheck($server, 95); + Notification::assertSentToTimes($server->team, HighDiskUsage::class, 1); + + Carbon::setTestNow(now()->addHour()); + runDiskUsageCheck($server, 40); + expect(NotificationThrottle::wasSent($server, HighDiskUsage::class))->toBeFalse(); + + Carbon::setTestNow(now()->addHour()); + runDiskUsageCheck($server, 92); + Notification::assertSentToTimes($server->team, HighDiskUsage::class, 2); +}); + it('defaults to one notification per 24 hours', function () { $team = Team::factory()->create(); $server = Server::factory()->create(['team_id' => $team->id]);