onQueue(maintenance_queue()); } public static function runningCacheKey(Server $server): string { return "server-patch-check-running:{$server->uuid}"; } /** * Queues a manual check and marks it as running, so the patches page shows the progress after a reload. */ public static function dispatchManual(Server $server): void { Cache::put(self::runningCacheKey($server), true, now()->addMinutes(15)); self::dispatch($server, true); } public function middleware(): array { return [(new WithoutOverlapping('server-patch-check-'.$this->server->uuid))->expireAfter(600)->dontRelease()]; } public function handle(): void { try { $team = data_get($this->server, 'team'); if (! $team || $this->server->isTransferredAway()) { return; } if ($this->server->isFunctional() === false) { if ($this->manual) { $this->saveResult(['error' => 'Server is not reachable or not ready.']); } return; } $previousError = $this->server->settings->patch_check_error; $patchData = CheckUpdates::run($this->server); $this->saveResult($patchData); if (isset($patchData['error'])) { // Notify only when the state changes from ok to error, not on every check of a broken server. if (blank($previousError)) { $team->notify(new ServerPatchCheck($this->server, $patchData)); } return; } if (! $this->manual && ($patchData['total_updates'] ?? 0) > 0) { $team->notify(new ServerPatchCheck($this->server, $patchData)); } } catch (\Throwable $e) { Log::error('ServerPatchCheckJob failed: '.$e->getMessage(), [ 'server_id' => $this->server->id, 'server_name' => $this->server->name, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); $this->saveResult(['error' => $e->getMessage()]); } finally { Cache::forget(self::runningCacheKey($this->server)); ServerPatchCheckFinished::dispatch($this->server->team_id, $this->server->uuid); } } /** * @param array $patchData */ private function saveResult(array $patchData): void { $error = $patchData['error'] ?? null; $this->server->settings->forceFill([ 'patch_check_result' => $error === null ? $patchData : Arr::only($patchData, ['osId', 'package_manager']), 'patch_check_error' => $error === null ? null : (string) $error, 'patch_checked_at' => now(), ])->saveQuietly(); } }