From 9a4b4280be5ad6e238cea4ffc267d64c8cd5289a Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sat, 28 Feb 2026 18:37:51 +0100 Subject: [PATCH] refactor(jobs): split task skip checks into critical and runtime phases Move expensive runtime checks (service/application status) after cron validation to avoid running them for tasks that aren't due. Critical checks (orphans, infrastructure) remain in first phase. Also fix database heading parameters to be built from the model. --- app/Jobs/ScheduledJobManager.php | 49 ++++++++++++++++------- app/Livewire/Project/Database/Heading.php | 6 ++- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/Jobs/ScheduledJobManager.php b/app/Jobs/ScheduledJobManager.php index 4195a1946..e68e3b613 100644 --- a/app/Jobs/ScheduledJobManager.php +++ b/app/Jobs/ScheduledJobManager.php @@ -214,10 +214,12 @@ private function processScheduledTasks(): void foreach ($tasks as $task) { try { $server = $task->server(); - $skipReason = $this->getTaskSkipReason($task, $server); - if ($skipReason !== null) { + + // Phase 1: Critical checks (always — cheap, handles orphans and infra issues) + $criticalSkip = $this->getTaskCriticalSkipReason($task, $server); + if ($criticalSkip !== null) { $this->skippedCount++; - $this->logSkip('task', $skipReason, [ + $this->logSkip('task', $criticalSkip, [ 'task_id' => $task->id, 'task_name' => $task->name, 'team_id' => $server?->team_id, @@ -237,16 +239,31 @@ private function processScheduledTasks(): void $frequency = VALID_CRON_STRINGS[$frequency]; } - if ($this->shouldRunNow($frequency, $serverTimezone, "scheduled-task:{$task->id}")) { - ScheduledTaskJob::dispatch($task); - $this->dispatchedCount++; - Log::channel('scheduled')->info('Task dispatched', [ + if (! $this->shouldRunNow($frequency, $serverTimezone, "scheduled-task:{$task->id}")) { + continue; + } + + // Phase 2: Runtime checks (only when cron is due — avoids noise for stopped resources) + $runtimeSkip = $this->getTaskRuntimeSkipReason($task); + if ($runtimeSkip !== null) { + $this->skippedCount++; + $this->logSkip('task', $runtimeSkip, [ 'task_id' => $task->id, 'task_name' => $task->name, 'team_id' => $server->team_id, - 'server_id' => $server->id, ]); + + continue; } + + ScheduledTaskJob::dispatch($task); + $this->dispatchedCount++; + Log::channel('scheduled')->info('Task dispatched', [ + 'task_id' => $task->id, + 'task_name' => $task->name, + 'team_id' => $server->team_id, + 'server_id' => $server->id, + ]); } catch (\Exception $e) { Log::channel('scheduled-errors')->error('Error processing task', [ 'task_id' => $task->id, @@ -281,11 +298,8 @@ private function getBackupSkipReason(ScheduledDatabaseBackup $backup, ?Server $s return null; } - private function getTaskSkipReason(ScheduledTask $task, ?Server $server): ?string + private function getTaskCriticalSkipReason(ScheduledTask $task, ?Server $server): ?string { - $service = $task->service; - $application = $task->application; - if (blank($server)) { $task->delete(); @@ -300,17 +314,22 @@ private function getTaskSkipReason(ScheduledTask $task, ?Server $server): ?strin return 'subscription_unpaid'; } - if (! $service && ! $application) { + if (! $task->service && ! $task->application) { $task->delete(); return 'resource_deleted'; } - if ($application && str($application->status)->contains('running') === false) { + return null; + } + + private function getTaskRuntimeSkipReason(ScheduledTask $task): ?string + { + if ($task->application && str($task->application->status)->contains('running') === false) { return 'application_not_running'; } - if ($service && str($service->status)->contains('running') === false) { + if ($task->service && str($task->service->status)->contains('running') === false) { return 'service_not_running'; } diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index 8d3d8e294..c6c9a3c48 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -69,7 +69,11 @@ public function manualCheckStatus() public function mount() { - $this->parameters = get_route_parameters(); + $this->parameters = [ + 'project_uuid' => $this->database->environment->project->uuid, + 'environment_uuid' => $this->database->environment->uuid, + 'database_uuid' => $this->database->uuid, + ]; } public function stop()