From 8dcd6e449b2208d014e070fb06153aeb67d959bf Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 12:12:53 +0100 Subject: [PATCH 1/2] Added jobs to queeue pending health checks --- .env.example | 2 + .../Commands/PerformSiteHealthCheck.php | 4 +- app/Console/Commands/QueueHealthChecks.php | 57 +++++++++++++++++++ app/Jobs/CheckSiteHealth.php | 6 +- routes/console.php | 2 + 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 app/Console/Commands/QueueHealthChecks.php diff --git a/.env.example b/.env.example index c9a868c..5fb97bc 100644 --- a/.env.example +++ b/.env.example @@ -63,3 +63,5 @@ AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false VITE_APP_NAME="${APP_NAME}" + +HEALTH_CHECK_INTERVAL=24 diff --git a/app/Console/Commands/PerformSiteHealthCheck.php b/app/Console/Commands/PerformSiteHealthCheck.php index f8c63ad..d1aef18 100644 --- a/app/Console/Commands/PerformSiteHealthCheck.php +++ b/app/Console/Commands/PerformSiteHealthCheck.php @@ -25,10 +25,12 @@ class PerformSiteHealthCheck extends Command /** * Execute the console command. */ - public function handle() + public function handle(): int { CheckSiteHealth::dispatchSync( Site::findOrFail($this->input->getArgument('siteId')) ); + + return Command::SUCCESS; } } diff --git a/app/Console/Commands/QueueHealthChecks.php b/app/Console/Commands/QueueHealthChecks.php new file mode 100644 index 0000000..1d13aa9 --- /dev/null +++ b/app/Console/Commands/QueueHealthChecks.php @@ -0,0 +1,57 @@ +output->writeln('Pushing pending health checks'); + + Site::query() + ->whereDate('last_seen', '<', Carbon::now()->subHours(env('HEALTH_CHECK_INTERVAL', 24))) + ->chunkById( + 100, + function (Collection $chunk) { + // Show progress + $this->output->write('.'); + + $this->totalPushed += $chunk->count(); + + // Push each site check to queue + $chunk->each(fn($site) => CheckSiteHealth::dispatch($site)); + } + ); + + // Result + $this->output->writeln(""); + $this->output->writeln('Pushed ' . $this->totalPushed . ' pending jobs to queue'); + + return Command::SUCCESS; + } +} diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index 3e0ab36..c587245 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -6,6 +6,7 @@ use App\Models\Site; use App\Services\SiteConnectionService; +use Carbon\Carbon; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; @@ -33,7 +34,7 @@ public function handle(): void $healthData = collect($response); // Write updated data to DB - $this->site->update( + $this->site->fill( $healthData->only([ 'php_version', 'db_type', @@ -42,5 +43,8 @@ public function handle(): void 'server_os' ])->toArray() ); + + $this->site->last_seen = Carbon::now(); + $this->site->save(); } } diff --git a/routes/console.php b/routes/console.php index ec6db2f..b05cd0e 100644 --- a/routes/console.php +++ b/routes/console.php @@ -2,5 +2,7 @@ use Illuminate\Support\Facades\Schedule; use Illuminate\Queue\Console\PruneFailedJobsCommand; +use App\Console\Commands\QueueHealthChecks; Schedule::command(PruneFailedJobsCommand::class)->daily(); +Schedule::command(QueueHealthChecks::class)->everyFifteenMinutes(); From 680440f7ff4d565b12021aea365053e67bc426ec Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 12:29:20 +0100 Subject: [PATCH 2/2] cs fixes --- app/Console/Commands/PerformSiteHealthCheck.php | 7 ++++--- app/Console/Commands/QueueHealthChecks.php | 8 ++++++-- app/Jobs/CheckSiteHealth.php | 1 + app/Services/SiteConnectionService.php | 15 +++++++++++++-- config/app.php | 3 +-- config/autoupdates.php | 5 +++++ phpstan.neon.dist | 7 +++++-- 7 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 config/autoupdates.php diff --git a/app/Console/Commands/PerformSiteHealthCheck.php b/app/Console/Commands/PerformSiteHealthCheck.php index d1aef18..856a977 100644 --- a/app/Console/Commands/PerformSiteHealthCheck.php +++ b/app/Console/Commands/PerformSiteHealthCheck.php @@ -27,9 +27,10 @@ class PerformSiteHealthCheck extends Command */ public function handle(): int { - CheckSiteHealth::dispatchSync( - Site::findOrFail($this->input->getArgument('siteId')) - ); + /** @var Site $site */ + $site = Site::findOrFail($this->input->getArgument('siteId')); + + CheckSiteHealth::dispatchSync($site); return Command::SUCCESS; } diff --git a/app/Console/Commands/QueueHealthChecks.php b/app/Console/Commands/QueueHealthChecks.php index 1d13aa9..06cd153 100644 --- a/app/Console/Commands/QueueHealthChecks.php +++ b/app/Console/Commands/QueueHealthChecks.php @@ -34,7 +34,11 @@ public function handle(): int $this->output->writeln('Pushing pending health checks'); Site::query() - ->whereDate('last_seen', '<', Carbon::now()->subHours(env('HEALTH_CHECK_INTERVAL', 24))) + ->whereDate( + 'last_seen', + '<', + Carbon::now()->subHours((int) config('autoupdates.healthcheck_interval')) // @phpstan-ignore-line + ) ->chunkById( 100, function (Collection $chunk) { @@ -44,7 +48,7 @@ function (Collection $chunk) { $this->totalPushed += $chunk->count(); // Push each site check to queue - $chunk->each(fn($site) => CheckSiteHealth::dispatch($site)); + $chunk->each(fn ($site) => CheckSiteHealth::dispatch($site)); } ); diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index c587245..6de3a2c 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -44,6 +44,7 @@ public function handle(): void ])->toArray() ); + // @phpstan-ignore-next-line $this->site->last_seen = Carbon::now(); $this->site->save(); } diff --git a/app/Services/SiteConnectionService.php b/app/Services/SiteConnectionService.php index af19cb5..a855e9c 100644 --- a/app/Services/SiteConnectionService.php +++ b/app/Services/SiteConnectionService.php @@ -95,12 +95,23 @@ protected function performHttpRequest( ); } - // Return decoded body - return json_decode( + // Decode body + $return = json_decode( (string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR ); + + // Make sure it's an array + if (!is_array($return)) { + throw new RequestException( + "Invalid JSON body", + $request, + $response + ); + } + + return $return; } } diff --git a/config/app.php b/config/app.php index 7200021..c10c9c9 100644 --- a/config/app.php +++ b/config/app.php @@ -121,6 +121,5 @@ 'maintenance' => [ 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), 'store' => env('APP_MAINTENANCE_STORE', 'database'), - ], - + ] ]; diff --git a/config/autoupdates.php b/config/autoupdates.php new file mode 100644 index 0000000..8ca0839 --- /dev/null +++ b/config/autoupdates.php @@ -0,0 +1,5 @@ + env('HEALTH_CHECK_INTERVAL', 24) +]; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 23cd8c3..cde55cc 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,5 +7,8 @@ parameters: paths: - app/ - # Level 9 is the highest level - level: 5 + level: 9 + + ignoreErrors: + - '#Method .* return type has no value type specified in iterable type array.#' + - '#Method .* has parameter .* with no value type specified in iterable type array.#'