refactor(core): streamline container stopping process and reduce timeout duration; update related methods for consistency
This commit is contained in:
@@ -85,7 +85,6 @@ class RunRemoteProcess
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$processResult = $process->wait();
|
$processResult = $process->wait();
|
||||||
// $processResult = Process::timeout($timeout)->run($this->getCommand(), $this->handleOutput(...));
|
|
||||||
if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) {
|
if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) {
|
||||||
$status = ProcessStatus::ERROR;
|
$status = ProcessStatus::ERROR;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,54 +3,27 @@
|
|||||||
namespace App\Actions\Proxy;
|
namespace App\Actions\Proxy;
|
||||||
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Process\InvokedProcess;
|
|
||||||
use Illuminate\Support\Facades\Process;
|
|
||||||
use Lorisleiva\Actions\Concerns\AsAction;
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
class StopProxy
|
class StopProxy
|
||||||
{
|
{
|
||||||
use AsAction;
|
use AsAction;
|
||||||
|
|
||||||
public function handle(Server $server, bool $forceStop = true)
|
public function handle(Server $server, bool $forceStop = true, int $timeout = 30)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$containerName = $server->isSwarm() ? 'coolify-proxy_traefik' : 'coolify-proxy';
|
$containerName = $server->isSwarm() ? 'coolify-proxy_traefik' : 'coolify-proxy';
|
||||||
$timeout = 30;
|
|
||||||
|
|
||||||
$process = $this->stopContainer($containerName, $timeout);
|
instant_remote_process(command: [
|
||||||
|
"docker stop --time=$timeout $containerName",
|
||||||
|
"docker rm -f $containerName",
|
||||||
|
], server: $server, throwError: false);
|
||||||
|
|
||||||
$startTime = Carbon::now()->getTimestamp();
|
|
||||||
while ($process->running()) {
|
|
||||||
if (Carbon::now()->getTimestamp() - $startTime >= $timeout) {
|
|
||||||
$this->forceStopContainer($containerName, $server);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->removeContainer($containerName, $server);
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
return handleError($e);
|
|
||||||
} finally {
|
|
||||||
$server->proxy->force_stop = $forceStop;
|
$server->proxy->force_stop = $forceStop;
|
||||||
$server->proxy->status = 'exited';
|
$server->proxy->status = 'exited';
|
||||||
$server->save();
|
$server->save();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function stopContainer(string $containerName, int $timeout): InvokedProcess
|
|
||||||
{
|
|
||||||
return Process::timeout($timeout)->start("docker stop --time=$timeout $containerName");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function forceStopContainer(string $containerName, Server $server)
|
|
||||||
{
|
|
||||||
instant_remote_process(["docker kill $containerName"], $server, throwError: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removeContainer(string $containerName, Server $server)
|
|
||||||
{
|
|
||||||
instant_remote_process(["docker rm -f $containerName"], $server, throwError: false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ namespace App\Livewire\Project\Application;
|
|||||||
use App\Actions\Docker\GetContainersStatus;
|
use App\Actions\Docker\GetContainersStatus;
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Models\ApplicationPreview;
|
use App\Models\ApplicationPreview;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Process\InvokedProcess;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Process;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Spatie\Url\Url;
|
use Spatie\Url\Url;
|
||||||
use Visus\Cuid2\Cuid2;
|
use Visus\Cuid2\Cuid2;
|
||||||
@@ -193,13 +190,12 @@ class Previews extends Component
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = $this->application->destination->server;
|
$server = $this->application->destination->server;
|
||||||
$timeout = 300;
|
|
||||||
|
|
||||||
if ($this->application->destination->server->isSwarm()) {
|
if ($this->application->destination->server->isSwarm()) {
|
||||||
instant_remote_process(["docker stack rm {$this->application->uuid}-{$pull_request_id}"], $server);
|
instant_remote_process(["docker stack rm {$this->application->uuid}-{$pull_request_id}"], $server);
|
||||||
} else {
|
} else {
|
||||||
$containers = getCurrentApplicationContainerStatus($server, $this->application->id, $pull_request_id)->toArray();
|
$containers = getCurrentApplicationContainerStatus($server, $this->application->id, $pull_request_id)->toArray();
|
||||||
$this->stopContainers($containers, $server, $timeout);
|
$this->stopContainers($containers, $server);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetContainersStatus::run($server);
|
GetContainersStatus::run($server);
|
||||||
@@ -215,13 +211,12 @@ class Previews extends Component
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = $this->application->destination->server;
|
$server = $this->application->destination->server;
|
||||||
$timeout = 300;
|
|
||||||
|
|
||||||
if ($this->application->destination->server->isSwarm()) {
|
if ($this->application->destination->server->isSwarm()) {
|
||||||
instant_remote_process(["docker stack rm {$this->application->uuid}-{$pull_request_id}"], $server);
|
instant_remote_process(["docker stack rm {$this->application->uuid}-{$pull_request_id}"], $server);
|
||||||
} else {
|
} else {
|
||||||
$containers = getCurrentApplicationContainerStatus($server, $this->application->id, $pull_request_id)->toArray();
|
$containers = getCurrentApplicationContainerStatus($server, $this->application->id, $pull_request_id)->toArray();
|
||||||
$this->stopContainers($containers, $server, $timeout);
|
$this->stopContainers($containers, $server);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationPreview::where('application_id', $this->application->id)
|
ApplicationPreview::where('application_id', $this->application->id)
|
||||||
@@ -237,48 +232,14 @@ class Previews extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function stopContainers(array $containers, $server, int $timeout)
|
private function stopContainers(array $containers, $server, int $timeout = 30)
|
||||||
{
|
{
|
||||||
$processes = [];
|
|
||||||
foreach ($containers as $container) {
|
foreach ($containers as $container) {
|
||||||
$containerName = str_replace('/', '', $container['Names']);
|
$containerName = str_replace('/', '', $container['Names']);
|
||||||
$processes[$containerName] = $this->stopContainer($containerName, $timeout);
|
instant_remote_process(command: [
|
||||||
}
|
"docker stop --time=$timeout $containerName",
|
||||||
|
"docker rm -f $containerName",
|
||||||
$startTime = Carbon::now()->getTimestamp();
|
], server: $server, throwError: false);
|
||||||
while (count($processes) > 0) {
|
|
||||||
$finishedProcesses = array_filter($processes, function ($process) {
|
|
||||||
return ! $process->running();
|
|
||||||
});
|
|
||||||
foreach (array_keys($finishedProcesses) as $containerName) {
|
|
||||||
unset($processes[$containerName]);
|
|
||||||
$this->removeContainer($containerName, $server);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Carbon::now()->getTimestamp() - $startTime >= $timeout) {
|
|
||||||
$this->forceStopRemainingContainers(array_keys($processes), $server);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function stopContainer(string $containerName, int $timeout): InvokedProcess
|
|
||||||
{
|
|
||||||
return Process::timeout($timeout)->start("docker stop --time=$timeout $containerName");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removeContainer(string $containerName, $server)
|
|
||||||
{
|
|
||||||
instant_remote_process(["docker rm -f $containerName"], $server, throwError: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function forceStopRemainingContainers(array $containerNames, $server)
|
|
||||||
{
|
|
||||||
foreach ($containerNames as $containerName) {
|
|
||||||
instant_remote_process(["docker kill $containerName"], $server, throwError: false);
|
|
||||||
$this->removeContainer($containerName, $server);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Process\InvokedProcess;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Process;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
@@ -270,47 +268,13 @@ class Application extends BaseModel
|
|||||||
return $containers->pluck('Names')->toArray();
|
return $containers->pluck('Names')->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stopContainers(array $containerNames, $server, int $timeout = 600)
|
public function stopContainers(array $containerNames, $server, int $timeout = 30)
|
||||||
{
|
|
||||||
$processes = [];
|
|
||||||
foreach ($containerNames as $containerName) {
|
|
||||||
$processes[$containerName] = $this->stopContainer($containerName, $server, $timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
$startTime = time();
|
|
||||||
while (count($processes) > 0) {
|
|
||||||
$finishedProcesses = array_filter($processes, function ($process) {
|
|
||||||
return ! $process->running();
|
|
||||||
});
|
|
||||||
foreach ($finishedProcesses as $containerName => $process) {
|
|
||||||
unset($processes[$containerName]);
|
|
||||||
$this->removeContainer($containerName, $server);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time() - $startTime >= $timeout) {
|
|
||||||
$this->forceStopRemainingContainers(array_keys($processes), $server);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stopContainer(string $containerName, $server, int $timeout): InvokedProcess
|
|
||||||
{
|
|
||||||
return Process::timeout($timeout)->start("docker stop --time=$timeout $containerName");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeContainer(string $containerName, $server)
|
|
||||||
{
|
|
||||||
instant_remote_process(command: ["docker rm -f $containerName"], server: $server, throwError: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function forceStopRemainingContainers(array $containerNames, $server)
|
|
||||||
{
|
{
|
||||||
foreach ($containerNames as $containerName) {
|
foreach ($containerNames as $containerName) {
|
||||||
instant_remote_process(command: ["docker kill $containerName"], server: $server, throwError: false);
|
instant_remote_process(command: [
|
||||||
$this->removeContainer($containerName, $server);
|
"docker stop --time=$timeout $containerName",
|
||||||
|
"docker rm -f $containerName",
|
||||||
|
], server: $server, throwError: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Process\InvokedProcess;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Process;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use OpenApi\Attributes as OA;
|
use OpenApi\Attributes as OA;
|
||||||
use Spatie\Url\Url;
|
use Spatie\Url\Url;
|
||||||
@@ -158,47 +156,13 @@ class Service extends BaseModel
|
|||||||
return $containersToStop;
|
return $containersToStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stopContainers(array $containerNames, $server, int $timeout = 300)
|
public function stopContainers(array $containerNames, $server, int $timeout = 30)
|
||||||
{
|
|
||||||
$processes = [];
|
|
||||||
foreach ($containerNames as $containerName) {
|
|
||||||
$processes[$containerName] = $this->stopContainer($containerName, $timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
$startTime = time();
|
|
||||||
while (count($processes) > 0) {
|
|
||||||
$finishedProcesses = array_filter($processes, function ($process) {
|
|
||||||
return ! $process->running();
|
|
||||||
});
|
|
||||||
foreach (array_keys($finishedProcesses) as $containerName) {
|
|
||||||
unset($processes[$containerName]);
|
|
||||||
$this->removeContainer($containerName, $server);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time() - $startTime >= $timeout) {
|
|
||||||
$this->forceStopRemainingContainers(array_keys($processes), $server);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stopContainer(string $containerName, int $timeout): InvokedProcess
|
|
||||||
{
|
|
||||||
return Process::timeout($timeout)->start("docker stop --time=$timeout $containerName");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeContainer(string $containerName, $server)
|
|
||||||
{
|
|
||||||
instant_remote_process(command: ["docker rm -f $containerName"], server: $server, throwError: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function forceStopRemainingContainers(array $containerNames, $server)
|
|
||||||
{
|
{
|
||||||
foreach ($containerNames as $containerName) {
|
foreach ($containerNames as $containerName) {
|
||||||
instant_remote_process(command: ["docker kill $containerName"], server: $server, throwError: false);
|
instant_remote_process(command: [
|
||||||
$this->removeContainer($containerName, $server);
|
"docker stop --time=$timeout $containerName",
|
||||||
|
"docker rm -f $containerName",
|
||||||
|
], server: $server, throwError: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,8 @@
|
|||||||
@script
|
@script
|
||||||
<script>
|
<script>
|
||||||
$wire.$on('stopEvent', () => {
|
$wire.$on('stopEvent', () => {
|
||||||
$wire.$dispatch('info', 'Stopping application.');
|
$wire.$dispatch('info',
|
||||||
|
'Gracefully stopping application, it could take a while depending on the application.');
|
||||||
$wire.$call('stop');
|
$wire.$call('stop');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -138,7 +138,7 @@
|
|||||||
@script
|
@script
|
||||||
<script>
|
<script>
|
||||||
$wire.$on('stopEvent', () => {
|
$wire.$on('stopEvent', () => {
|
||||||
$wire.$dispatch('info', 'Stopping service.');
|
$wire.$dispatch('info', 'Gracefully stopping service, it could take a while depending on the service.');
|
||||||
$wire.$call('stop');
|
$wire.$call('stop');
|
||||||
});
|
});
|
||||||
$wire.$on('startEvent', async () => {
|
$wire.$on('startEvent', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user