diff --git a/app/Actions/Application/StopApplication.php b/app/Actions/Application/StopApplication.php index b79709c5a..bfad20ccf 100644 --- a/app/Actions/Application/StopApplication.php +++ b/app/Actions/Application/StopApplication.php @@ -13,7 +13,7 @@ class StopApplication public string $jobQueue = 'high'; - public function handle(Application $application, bool $previewDeployments = false, bool $dockerCleanup = true) + public function handle(Application $application, bool $previewDeployments = false, bool $dockerCleanup = true, bool $resetRestartCount = true) { $servers = collect([$application->destination->server]); if ($application?->additional_servers?->count() > 0) { @@ -57,12 +57,17 @@ class StopApplication } } - // Reset restart tracking when application is manually stopped - $application->update([ - 'restart_count' => 0, - 'last_restart_at' => null, - 'last_restart_type' => null, - ]); + if ($resetRestartCount) { + $application->update([ + 'restart_count' => 0, + 'last_restart_at' => null, + 'last_restart_type' => null, + ]); + } else { + $application->update([ + 'status' => 'exited', + ]); + } ServiceStatusChanged::dispatch($application->environment->project->team->id); } diff --git a/app/Actions/Docker/GetContainersStatus.php b/app/Actions/Docker/GetContainersStatus.php index cfac83583..904885dfc 100644 --- a/app/Actions/Docker/GetContainersStatus.php +++ b/app/Actions/Docker/GetContainersStatus.php @@ -466,7 +466,9 @@ class GetContainersStatus } // Wrap all database updates in a transaction to ensure consistency - DB::transaction(function () use ($application, $maxRestartCount, $containerStatuses) { + $restartLimitReached = false; + + DB::transaction(function () use ($application, $maxRestartCount, $containerStatuses, &$restartLimitReached) { $previousRestartCount = $application->restart_count ?? 0; if ($maxRestartCount > $previousRestartCount) { @@ -480,8 +482,7 @@ class GetContainersStatus // Check if restart limit has been reached $maxAllowedRestarts = $application->max_restart_count ?? 0; if ($maxAllowedRestarts > 0 && $maxRestartCount >= $maxAllowedRestarts && $previousRestartCount < $maxAllowedRestarts) { - StopApplication::dispatch($application); - $application->environment->project->team?->notify(new ApplicationRestartLimitReached($application)); + $restartLimitReached = true; } } @@ -496,6 +497,12 @@ class GetContainersStatus } } }); + + if ($restartLimitReached) { + $application->refresh(); + StopApplication::dispatch($application, false, true, false); + $application->environment->project->team?->notify(new ApplicationRestartLimitReached($application)); + } } } diff --git a/app/Models/Application.php b/app/Models/Application.php index eee67022f..1ffa62584 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -572,6 +572,15 @@ class Application extends BaseModel return null; } + public function stoppedAfterRestartLimit(): bool + { + return str($this->status)->startsWith('exited') + && ($this->restart_count ?? 0) > 0 + && ($this->max_restart_count ?? 0) > 0 + && $this->restart_count >= $this->max_restart_count + && $this->last_restart_type === 'crash'; + } + public function taskLink($task_uuid) { if (data_get($this, 'environment.project.uuid')) { diff --git a/app/Notifications/Application/RestartLimitReached.php b/app/Notifications/Application/RestartLimitReached.php index 8709e7cd3..635dfdbdc 100644 --- a/app/Notifications/Application/RestartLimitReached.php +++ b/app/Notifications/Application/RestartLimitReached.php @@ -30,6 +30,7 @@ class RestartLimitReached extends CustomEmailNotification public function __construct(public Application $resource) { $this->onQueue('high'); + $this->afterCommit(); $this->resource_name = data_get($resource, 'name'); $this->project_uuid = data_get($resource, 'environment.project.uuid'); $this->environment_uuid = data_get($resource, 'environment.uuid'); @@ -40,7 +41,7 @@ class RestartLimitReached extends CustomEmailNotification if (str($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = str($this->fqdn)->explode(',')->first(); } - $this->resource_url = base_url()."/project/{$this->project_uuid}/environment/{$this->environment_uuid}/application/{$this->resource->uuid}"; + $this->resource_url = $this->resource->link() ?? base_url()."/project/{$this->project_uuid}/environment/{$this->environment_uuid}/application/{$this->resource->uuid}"; } public function via(object $notifiable): array diff --git a/resources/views/components/status/index.blade.php b/resources/views/components/status/index.blade.php index 8d959ce6e..b54e35bd5 100644 --- a/resources/views/components/status/index.blade.php +++ b/resources/views/components/status/index.blade.php @@ -2,7 +2,11 @@ 'title' => null, 'lastDeploymentLink' => null, 'resource' => null, + 'showRefreshButton' => true, ]) +@php + $stoppedAfterRestartLimit = $resource && method_exists($resource, 'stoppedAfterRestartLimit') && $resource->stoppedAfterRestartLimit(); +@endphp
@if (str($resource->status)->startsWith('running')) @@ -13,13 +17,20 @@ @else @endif - @if (isset($resource->restart_count) && $resource->restart_count > 0 && !str($resource->status)->startsWith('exited')) + @if (isset($resource->restart_count) && $resource->restart_count > 0 && (!str($resource->status)->startsWith('exited') || $stoppedAfterRestartLimit))
({{ $resource->restart_count }}x restarts)
@endif + @if ($stoppedAfterRestartLimit) +
+ + Stopped after reaching restart limit ({{ $resource->restart_count }}/{{ $resource->max_restart_count }}). + +
+ @endif @if (!str($resource->status)->contains('exited') && $showRefreshButton)