diff --git a/app/Actions/Database/ManageBackup.php b/app/Actions/Database/ManageBackup.php index 70d335b0..eaacc5f7 100644 --- a/app/Actions/Database/ManageBackup.php +++ b/app/Actions/Database/ManageBackup.php @@ -65,7 +65,7 @@ public function delete(Backup $backup): void } $backup->delete(); - }); + })->onQueue('ssh'); } /** diff --git a/app/Actions/Database/ManageBackupFile.php b/app/Actions/Database/ManageBackupFile.php index 9d9bf38c..d14df882 100644 --- a/app/Actions/Database/ManageBackupFile.php +++ b/app/Actions/Database/ManageBackupFile.php @@ -30,6 +30,6 @@ public function delete(BackupFile $file): void dispatch(function () use ($file): void { $file->deleteFile(); - }); + })->onQueue('ssh'); } } diff --git a/app/Actions/Database/RestoreBackup.php b/app/Actions/Database/RestoreBackup.php index b12a0176..e61745c0 100644 --- a/app/Actions/Database/RestoreBackup.php +++ b/app/Actions/Database/RestoreBackup.php @@ -37,7 +37,7 @@ public function restore(BackupFile $backupFile, array $input): void })->catch(function () use ($backupFile): void { $backupFile->status = BackupFileStatus::RESTORE_FAILED; $backupFile->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } /** diff --git a/app/Actions/Database/RunBackup.php b/app/Actions/Database/RunBackup.php index c9d473ef..3fec0bb3 100644 --- a/app/Actions/Database/RunBackup.php +++ b/app/Actions/Database/RunBackup.php @@ -39,7 +39,7 @@ public function run(Backup $backup): BackupFile $backup->save(); $file->status = BackupFileStatus::FAILED; $file->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); return $file; } diff --git a/app/Actions/FirewallRule/ManageRule.php b/app/Actions/FirewallRule/ManageRule.php index 6791915f..b2399566 100755 --- a/app/Actions/FirewallRule/ManageRule.php +++ b/app/Actions/FirewallRule/ManageRule.php @@ -34,7 +34,7 @@ public function create(Server $server, array $input): FirewallRule $rule->save(); - dispatch(fn () => $this->applyRule($rule)); + dispatch(fn () => $this->applyRule($rule))->onQueue('ssh'); return $rule; } @@ -58,7 +58,7 @@ public function update(FirewallRule $rule, array $input): FirewallRule 'status' => FirewallRuleStatus::UPDATING, ]); - dispatch(fn () => $this->applyRule($rule)); + dispatch(fn () => $this->applyRule($rule))->onQueue('ssh'); return $rule; } @@ -68,7 +68,7 @@ public function delete(FirewallRule $rule): void $rule->status = FirewallRuleStatus::DELETING; $rule->save(); - dispatch(fn () => $this->applyRule($rule)); + dispatch(fn () => $this->applyRule($rule))->onQueue('ssh'); } protected function applyRule(FirewallRule $rule): void diff --git a/app/Actions/PHP/InstallPHPExtension.php b/app/Actions/PHP/InstallPHPExtension.php index 958a96d3..c47c452e 100755 --- a/app/Actions/PHP/InstallPHPExtension.php +++ b/app/Actions/PHP/InstallPHPExtension.php @@ -44,7 +44,7 @@ function () use ($service, $input): void { $typeData['extensions'] = array_values(array_diff($typeData['extensions'], [$input['extension']])); $service->type_data = $typeData; $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); return $service; } diff --git a/app/Actions/Redirect/CreateRedirect.php b/app/Actions/Redirect/CreateRedirect.php index fd667721..61b101e9 100644 --- a/app/Actions/Redirect/CreateRedirect.php +++ b/app/Actions/Redirect/CreateRedirect.php @@ -43,7 +43,7 @@ public function create(Site $site, array $input): Redirect $redirect->status = RedirectStatus::FAILED; $redirect->save(); }) - ->onConnection('ssh'); + ->onQueue('ssh-unique'); return $redirect->refresh(); } diff --git a/app/Actions/Redirect/DeleteRedirect.php b/app/Actions/Redirect/DeleteRedirect.php index cf8f6d80..2763bb6d 100644 --- a/app/Actions/Redirect/DeleteRedirect.php +++ b/app/Actions/Redirect/DeleteRedirect.php @@ -27,6 +27,6 @@ public function delete(Site $site, Redirect $redirect): void })->catch(function () use ($redirect): void { $redirect->status = RedirectStatus::FAILED; $redirect->save(); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); } } diff --git a/app/Actions/SSL/CreateSSL.php b/app/Actions/SSL/CreateSSL.php index 6172d1df..59e3ff13 100644 --- a/app/Actions/SSL/CreateSSL.php +++ b/app/Actions/SSL/CreateSSL.php @@ -60,7 +60,7 @@ public function create(Site $site, array $input): void })->catch(function () use ($ssl): void { $ssl->status = SslStatus::FAILED; $ssl->save(); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); } /** diff --git a/app/Actions/Script/ExecuteScript.php b/app/Actions/Script/ExecuteScript.php index bb70d284..799d92d6 100644 --- a/app/Actions/Script/ExecuteScript.php +++ b/app/Actions/Script/ExecuteScript.php @@ -62,7 +62,7 @@ public function execute(Script $script, User $user, array $input): ScriptExecuti })->catch(function () use ($execution): void { $execution->status = ScriptExecutionStatus::FAILED; $execution->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); return $execution; } diff --git a/app/Actions/Server/CreateServer.php b/app/Actions/Server/CreateServer.php index 63c00140..6a6e801f 100755 --- a/app/Actions/Server/CreateServer.php +++ b/app/Actions/Server/CreateServer.php @@ -81,7 +81,7 @@ public function create(User $creator, Project $project, array $input): Server 'error' => (string) $e, ]); }) - ->onConnection('ssh'); + ->onQueue('ssh'); return $this->server; } catch (Exception $e) { diff --git a/app/Actions/Server/Update.php b/app/Actions/Server/Update.php index 06a08e2d..3cf2e8bb 100644 --- a/app/Actions/Server/Update.php +++ b/app/Actions/Server/Update.php @@ -20,6 +20,6 @@ public function update(Server $server): void })->catch(function () use ($server): void { Notifier::send($server, new ServerUpdateFailed($server)); $server->checkConnection(); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); } } diff --git a/app/Actions/Service/Install.php b/app/Actions/Service/Install.php index d2fc068a..105dbf9d 100644 --- a/app/Actions/Service/Install.php +++ b/app/Actions/Service/Install.php @@ -46,7 +46,7 @@ public function install(Server $server, array $input): Service })->catch(function () use ($service): void { $service->status = ServiceStatus::INSTALLATION_FAILED; $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); return $service; } diff --git a/app/Actions/Service/Manage.php b/app/Actions/Service/Manage.php index bada2a95..2d53ce7f 100644 --- a/app/Actions/Service/Manage.php +++ b/app/Actions/Service/Manage.php @@ -21,7 +21,7 @@ public function start(Service $service): void $service->status = ServiceStatus::FAILED; } $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } public function stop(Service $service): void @@ -37,7 +37,7 @@ public function stop(Service $service): void $service->status = ServiceStatus::FAILED; } $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } public function restart(Service $service): void @@ -53,7 +53,7 @@ public function restart(Service $service): void $service->status = ServiceStatus::FAILED; } $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } public function enable(Service $service): void @@ -69,7 +69,7 @@ public function enable(Service $service): void $service->status = ServiceStatus::FAILED; } $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } public function disable(Service $service): void @@ -85,7 +85,7 @@ public function disable(Service $service): void $service->status = ServiceStatus::FAILED; } $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } private function validate(Service $service): void diff --git a/app/Actions/Service/Uninstall.php b/app/Actions/Service/Uninstall.php index f3ccb8db..86bd7901 100644 --- a/app/Actions/Service/Uninstall.php +++ b/app/Actions/Service/Uninstall.php @@ -26,6 +26,6 @@ public function uninstall(Service $service): void })->catch(function () use ($service): void { $service->status = ServiceStatus::FAILED; $service->save(); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); } } diff --git a/app/Actions/Site/CreateSite.php b/app/Actions/Site/CreateSite.php index 81dcf8f8..ab545c31 100755 --- a/app/Actions/Site/CreateSite.php +++ b/app/Actions/Site/CreateSite.php @@ -92,7 +92,7 @@ public function create(Server $server, array $input): Site $site->status = SiteStatus::INSTALLATION_FAILED; $site->save(); Notifier::send($site, new SiteInstallationFailed($site)); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); DB::commit(); diff --git a/app/Actions/Site/Deploy.php b/app/Actions/Site/Deploy.php index e262e5ff..b23fefb2 100644 --- a/app/Actions/Site/Deploy.php +++ b/app/Actions/Site/Deploy.php @@ -57,7 +57,7 @@ public function run(Site $site): Deployment $deployment->status = DeploymentStatus::FAILED; $deployment->save(); Notifier::send($site, new DeploymentCompleted($deployment, $site)); - })->onConnection('ssh'); + })->onQueue('ssh-unique'); return $deployment; } diff --git a/app/Actions/Site/ExecuteCommand.php b/app/Actions/Site/ExecuteCommand.php index adad9666..2dc2777a 100644 --- a/app/Actions/Site/ExecuteCommand.php +++ b/app/Actions/Site/ExecuteCommand.php @@ -55,7 +55,7 @@ public function execute(Command $command, User $user, array $input): CommandExec })->catch(function () use ($execution): void { $execution->status = CommandExecutionStatus::FAILED; $execution->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); return $execution; } diff --git a/app/Actions/Worker/CreateWorker.php b/app/Actions/Worker/CreateWorker.php index aa98d904..be4283fe 100644 --- a/app/Actions/Worker/CreateWorker.php +++ b/app/Actions/Worker/CreateWorker.php @@ -55,7 +55,7 @@ public function create(Server $server, array $input, ?Site $site = null): void $worker->save(); })->catch(function () use ($worker): void { $worker->delete(); - })->onConnection('ssh'); + })->onQueue('ssh'); } /** diff --git a/app/Actions/Worker/EditWorker.php b/app/Actions/Worker/EditWorker.php index f3273a48..d16b698f 100644 --- a/app/Actions/Worker/EditWorker.php +++ b/app/Actions/Worker/EditWorker.php @@ -55,7 +55,7 @@ public function edit(Worker $worker, array $input): void })->catch(function () use ($worker): void { $worker->status = WorkerStatus::FAILED; $worker->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } /** diff --git a/app/Actions/Worker/ManageWorker.php b/app/Actions/Worker/ManageWorker.php index deee226f..6798278b 100644 --- a/app/Actions/Worker/ManageWorker.php +++ b/app/Actions/Worker/ManageWorker.php @@ -21,7 +21,7 @@ public function start(Worker $worker): void $handler->start($worker->id, $worker->site_id); $worker->status = WorkerStatus::RUNNING; $worker->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } public function stop(Worker $worker): void @@ -36,7 +36,7 @@ public function stop(Worker $worker): void $handler->stop($worker->id, $worker->site_id); $worker->status = WorkerStatus::STOPPED; $worker->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } public function restart(Worker $worker): void @@ -51,6 +51,6 @@ public function restart(Worker $worker): void $handler->restart($worker->id, $worker->site_id); $worker->status = WorkerStatus::RUNNING; $worker->save(); - })->onConnection('ssh'); + })->onQueue('ssh'); } } diff --git a/app/Console/Commands/CheckServersConnectionCommand.php b/app/Console/Commands/CheckServersConnectionCommand.php index 57d4b74a..738d94e7 100644 --- a/app/Console/Commands/CheckServersConnectionCommand.php +++ b/app/Console/Commands/CheckServersConnectionCommand.php @@ -27,7 +27,7 @@ public function handle(): void return; } $server->checkConnection(); - })->onConnection('ssh'); + })->onQueue('ssh'); } }); } diff --git a/app/Helpers/Agent.php b/app/Helpers/Agent.php index 91a9646a..2a247952 100644 --- a/app/Helpers/Agent.php +++ b/app/Helpers/Agent.php @@ -12,7 +12,7 @@ class Agent extends MobileDetect * * @var array */ - protected static $additionalOperatingSystems = [ + protected static array $additionalOperatingSystems = [ 'Windows' => 'Windows', 'Windows NT' => 'Windows NT', 'OS X' => 'Mac OS X', @@ -29,7 +29,7 @@ class Agent extends MobileDetect * * @var array */ - protected static $additionalBrowsers = [ + protected static array $additionalBrowsers = [ 'Opera Mini' => 'Opera Mini', 'Opera' => 'Opera|OPR', 'Edge' => 'Edge|Edg', @@ -50,14 +50,12 @@ class Agent extends MobileDetect * * @var array */ - protected $store = []; + protected array $store = []; /** * Get the platform name from the User Agent. - * - * @return string|null */ - public function platform() + public function platform(): ?string { return $this->retrieveUsingCacheOrResolve('paymently.platform', fn () => $this->findDetectionRulesAgainstUserAgent( $this->mergeRules(MobileDetect::getOperatingSystems(), static::$additionalOperatingSystems) diff --git a/app/Http/Controllers/PluginController.php b/app/Http/Controllers/PluginController.php index 68251b4b..3bfc5d6d 100644 --- a/app/Http/Controllers/PluginController.php +++ b/app/Http/Controllers/PluginController.php @@ -58,8 +58,7 @@ public function install(Request $request): RedirectResponse } Plugins::cleanup(); - }) - ->onConnection('default'); + })->onQueue('default'); return back()->with('info', 'Plugin is being installed...'); } @@ -89,8 +88,7 @@ public function uninstall(Request $request): RedirectResponse } Plugins::cleanup(); - }) - ->onConnection('default'); + })->onQueue('default'); return back()->with('warning', 'Plugin is being uninstalled...'); } diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php new file mode 100644 index 00000000..27332285 --- /dev/null +++ b/app/Providers/HorizonServiceProvider.php @@ -0,0 +1,35 @@ +isAdmin(); + }); + } +} diff --git a/app/SourceControlProviders/Gitlab.php b/app/SourceControlProviders/Gitlab.php index 51d76dd4..a211e2e7 100755 --- a/app/SourceControlProviders/Gitlab.php +++ b/app/SourceControlProviders/Gitlab.php @@ -34,15 +34,12 @@ public function createRules(array $input): array public function connect(): bool { try { - ds($this->getApiUrl()); $res = Http::withToken($this->data()['token']) ->get($this->getApiUrl().'/version'); } catch (Exception) { return false; } - ds($res->status()); - return $res->successful(); } diff --git a/composer.json b/composer.json index c40e0f14..0589cc70 100644 --- a/composer.json +++ b/composer.json @@ -13,9 +13,9 @@ "ext-intl": "*", "aws/aws-sdk-php": "^3.158", "inertiajs/inertia-laravel": "^2.0", - "laradumps/laradumps": "^4.2", "laravel/fortify": "^1.17", "laravel/framework": "^12.0", + "laravel/horizon": "^5.33", "laravel/sanctum": "^4.0", "laravel/tinker": "^2.8", "mobiledetect/mobiledetectlib": "^4.8", diff --git a/composer.lock b/composer.lock index 879cf83f..233eef7f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fc8ee6c13042c4df2cd39b59c4d80ac1", + "content-hash": "b7e394815fa2fc2447c357d65eda06e7", "packages": [ { "name": "aws/aws-crt-php", @@ -1377,147 +1377,6 @@ }, "time": "2025-04-10T15:08:36+00:00" }, - { - "name": "laradumps/laradumps", - "version": "v4.2.1", - "source": { - "type": "git", - "url": "https://github.com/laradumps/laradumps.git", - "reference": "0cdd5fe9e20efc71c280a97a6aca3a05c19469f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps/zipball/0cdd5fe9e20efc71c280a97a6aca3a05c19469f6", - "reference": "0cdd5fe9e20efc71c280a97a6aca3a05c19469f6", - "shasum": "" - }, - "require": { - "illuminate/mail": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", - "laradumps/laradumps-core": "^3.2.2", - "nunomaduro/termwind": "^1.15.1|^2.0.1", - "php": "^8.1" - }, - "require-dev": { - "larastan/larastan": "^2.0|^3.0", - "laravel/framework": "^10.0|^11.0|^12.0", - "laravel/pint": "^1.17.2", - "livewire/livewire": "^3.5.6", - "mockery/mockery": "^1.6.12", - "orchestra/testbench-core": "^8.0|^9.4|^10.0", - "pestphp/pest": "^2.35.1|^3.7.0", - "symfony/var-dumper": "^6.4.0|^7.1.3" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "LaraDumps\\LaraDumps\\LaraDumpsServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LaraDumps\\LaraDumps\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luan Freitas", - "email": "luanfreitas10@protonmail.com", - "role": "Developer" - } - ], - "description": "LaraDumps is a friendly app designed to boost your Laravel PHP coding and debugging experience.", - "homepage": "https://github.com/laradumps/laradumps", - "support": { - "issues": "https://github.com/laradumps/laradumps/issues", - "source": "https://github.com/laradumps/laradumps/tree/v4.2.1" - }, - "funding": [ - { - "url": "https://github.com/luanfreitasdev", - "type": "github" - } - ], - "time": "2025-06-12T13:38:57+00:00" - }, - { - "name": "laradumps/laradumps-core", - "version": "v3.2.4", - "source": { - "type": "git", - "url": "https://github.com/laradumps/laradumps-core.git", - "reference": "eb0e15805ac4061a524c43ed7c1e7796ef3326d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/eb0e15805ac4061a524c43ed7c1e7796ef3326d8", - "reference": "eb0e15805ac4061a524c43ed7c1e7796ef3326d8", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "nunomaduro/termwind": "^1.15|^2.0", - "php": "^8.1", - "ramsey/uuid": "^4.7.5", - "spatie/backtrace": "^1.5", - "symfony/console": "^5.4|^6.4|^7.0", - "symfony/finder": "^5.4|^6.4|^7.0", - "symfony/process": "^5.4|^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.4|^7.0", - "symfony/yaml": "^5.4|^6.4|^7.0" - }, - "require-dev": { - "illuminate/support": "^10.46", - "laravel/pint": "^1.13.7", - "pestphp/pest": "^2.0|^3.0", - "phpstan/phpstan": "^1.10.50" - }, - "bin": [ - "bin/laradumps" - ], - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LaraDumps\\LaraDumpsCore\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luan Freitas", - "email": "luanfreitas10@protonmail.com", - "role": "Developer" - } - ], - "description": "LaraDumps is a friendly app designed to boost your Laravel / PHP coding and debugging experience.", - "homepage": "https://github.com/laradumps/laradumps-core", - "support": { - "issues": "https://github.com/laradumps/laradumps-core/issues", - "source": "https://github.com/laradumps/laradumps-core/tree/v3.2.4" - }, - "funding": [ - { - "url": "https://github.com/luanfreitasdev", - "type": "github" - } - ], - "time": "2025-05-16T14:48:30+00:00" - }, { "name": "laravel/fortify", "version": "v1.27.0", @@ -1798,6 +1657,86 @@ }, "time": "2025-06-18T12:56:23+00:00" }, + { + "name": "laravel/horizon", + "version": "v5.33.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/horizon.git", + "reference": "50057bca1f1dcc9fbd5ff6d65143833babd784b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/horizon/zipball/50057bca1f1dcc9fbd5ff6d65143833babd784b3", + "reference": "50057bca1f1dcc9fbd5ff6d65143833babd784b3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcntl": "*", + "ext-posix": "*", + "illuminate/contracts": "^9.21|^10.0|^11.0|^12.0", + "illuminate/queue": "^9.21|^10.0|^11.0|^12.0", + "illuminate/support": "^9.21|^10.0|^11.0|^12.0", + "nesbot/carbon": "^2.17|^3.0", + "php": "^8.0", + "ramsey/uuid": "^4.0", + "symfony/console": "^6.0|^7.0", + "symfony/error-handler": "^6.0|^7.0", + "symfony/polyfill-php83": "^1.28", + "symfony/process": "^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.0|^10.4|^11.5", + "predis/predis": "^1.1|^2.0" + }, + "suggest": { + "ext-redis": "Required to use the Redis PHP driver.", + "predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0)." + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Horizon": "Laravel\\Horizon\\Horizon" + }, + "providers": [ + "Laravel\\Horizon\\HorizonServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Horizon\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Dashboard and code-driven configuration for Laravel queues.", + "keywords": [ + "laravel", + "queue" + ], + "support": { + "issues": "https://github.com/laravel/horizon/issues", + "source": "https://github.com/laravel/horizon/tree/v5.33.1" + }, + "time": "2025-06-16T13:48:30+00:00" + }, { "name": "laravel/prompts", "version": "v0.3.5", @@ -4465,69 +4404,6 @@ }, "time": "2025-06-01T06:28:46+00:00" }, - { - "name": "spatie/backtrace", - "version": "1.7.4", - "source": { - "type": "git", - "url": "https://github.com/spatie/backtrace.git", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/cd37a49fce7137359ac30ecc44ef3e16404cccbe", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "ext-json": "*", - "laravel/serializable-closure": "^1.3 || ^2.0", - "phpunit/phpunit": "^9.3 || ^11.4.3", - "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6", - "symfony/var-dumper": "^5.1 || ^6.0 || ^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Backtrace\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van de Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "A better backtrace", - "homepage": "https://github.com/spatie/backtrace", - "keywords": [ - "Backtrace", - "spatie" - ], - "support": { - "source": "https://github.com/spatie/backtrace/tree/1.7.4" - }, - "funding": [ - { - "url": "https://github.com/sponsors/spatie", - "type": "github" - }, - { - "url": "https://spatie.be/open-source/support-us", - "type": "other" - } - ], - "time": "2025-05-08T15:41:09+00:00" - }, { "name": "spatie/laravel-route-attributes", "version": "1.25.2", @@ -6834,78 +6710,6 @@ ], "time": "2025-04-27T18:39:23+00:00" }, - { - "name": "symfony/yaml", - "version": "v7.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "cea40a48279d58dc3efee8112634cb90141156c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/cea40a48279d58dc3efee8112634cb90141156c2", - "reference": "cea40a48279d58dc3efee8112634cb90141156c2", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2025-04-04T10:10:33+00:00" - }, { "name": "tightenco/ziggy", "version": "v2.5.3", @@ -9854,6 +9658,69 @@ ], "time": "2024-02-20T11:51:46+00:00" }, + { + "name": "spatie/backtrace", + "version": "1.7.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/cd37a49fce7137359ac30ecc44ef3e16404cccbe", + "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "ext-json": "*", + "laravel/serializable-closure": "^1.3 || ^2.0", + "phpunit/phpunit": "^9.3 || ^11.4.3", + "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6", + "symfony/var-dumper": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/backtrace/tree/1.7.4" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2025-05-08T15:41:09+00:00" + }, { "name": "spatie/data-transfer-object", "version": "3.9.1", @@ -10364,6 +10231,78 @@ ], "time": "2025-05-15T09:04:05+00:00" }, + { + "name": "symfony/yaml", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "cea40a48279d58dc3efee8112634cb90141156c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/cea40a48279d58dc3efee8112634cb90141156c2", + "reference": "cea40a48279d58dc3efee8112634cb90141156c2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-04T10:10:33+00:00" + }, { "name": "theseer/tokenizer", "version": "1.2.3", diff --git a/config/app.php b/config/app.php index 0b61e54a..a131bb31 100644 --- a/config/app.php +++ b/config/app.php @@ -200,6 +200,7 @@ App\Providers\SourceControlServiceProvider::class, App\Providers\NotificationChannelServiceProvider::class, App\Providers\ServiceTypeServiceProvider::class, + App\Providers\HorizonServiceProvider::class, ], /* diff --git a/config/horizon.php b/config/horizon.php new file mode 100644 index 00000000..6f0e5b2a --- /dev/null +++ b/config/horizon.php @@ -0,0 +1,242 @@ + env('HORIZON_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | Horizon Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Horizon will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => env('HORIZON_PATH', 'horizon'), + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Connection + |-------------------------------------------------------------------------- + | + | This is the name of the Redis connection where Horizon will store the + | meta information required for it to function. It includes the list + | of supervisors, failed jobs, job metrics, and other information. + | + */ + + 'use' => 'default', + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Prefix + |-------------------------------------------------------------------------- + | + | This prefix will be used when storing all Horizon data in Redis. You + | may modify the prefix when you are running multiple installations + | of Horizon on the same server so that they don't have problems. + | + */ + + 'prefix' => env( + 'HORIZON_PREFIX', + Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:' + ), + + /* + |-------------------------------------------------------------------------- + | Horizon Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will get attached onto each Horizon route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + \App\Http\Middleware\MustBeAdminMiddleware::class, + ], + + /* + |-------------------------------------------------------------------------- + | Queue Wait Time Thresholds + |-------------------------------------------------------------------------- + | + | This option allows you to configure when the LongWaitDetected event + | will be fired. Every connection / queue combination may have its + | own, unique threshold (in seconds) before this event is fired. + | + */ + + 'waits' => [ + 'redis:default' => 60, + ], + + /* + |-------------------------------------------------------------------------- + | Job Trimming Times + |-------------------------------------------------------------------------- + | + | Here you can configure for how long (in minutes) you desire Horizon to + | persist the recent and failed jobs. Typically, recent jobs are kept + | for one hour while all failed jobs are stored for an entire week. + | + */ + + 'trim' => [ + 'recent' => 60, + 'pending' => 60, + 'completed' => 60, + 'recent_failed' => 10080, + 'failed' => 10080, + 'monitored' => 10080, + ], + + /* + |-------------------------------------------------------------------------- + | Silenced Jobs + |-------------------------------------------------------------------------- + | + | Silencing a job will instruct Horizon to not place the job in the list + | of completed jobs within the Horizon dashboard. This setting may be + | used to fully remove any noisy jobs from the completed jobs list. + | + */ + + 'silenced' => [ + // App\Jobs\ExampleJob::class, + ], + + /* + |-------------------------------------------------------------------------- + | Metrics + |-------------------------------------------------------------------------- + | + | Here you can configure how many snapshots should be kept to display in + | the metrics graph. This will get used in combination with Horizon's + | `horizon:snapshot` schedule to define how long to retain metrics. + | + */ + + 'metrics' => [ + 'trim_snapshots' => [ + 'job' => 24, + 'queue' => 24, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Fast Termination + |-------------------------------------------------------------------------- + | + | When this option is enabled, Horizon's "terminate" command will not + | wait on all of the workers to terminate unless the --wait option + | is provided. Fast termination can shorten deployment delay by + | allowing a new instance of Horizon to start while the last + | instance will continue to terminate each of its workers. + | + */ + + 'fast_termination' => false, + + /* + |-------------------------------------------------------------------------- + | Memory Limit (MB) + |-------------------------------------------------------------------------- + | + | This value describes the maximum amount of memory the Horizon master + | supervisor may consume before it is terminated and restarted. For + | configuring these limits on your workers, see the next section. + | + */ + + 'memory_limit' => 64, + + /* + |-------------------------------------------------------------------------- + | Queue Worker Configuration + |-------------------------------------------------------------------------- + | + | Here you may define the queue worker settings used by your application + | in all environments. These supervisors and settings handle all your + | queued jobs and will be provisioned by Horizon during deployment. + | + */ + + 'defaults' => [ + 'default' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'auto', + 'autoScalingStrategy' => 'time', + 'maxProcesses' => 1, + 'maxTime' => 0, + 'maxJobs' => 0, + 'memory' => 128, + 'tries' => 1, + 'timeout' => 90, + 'nice' => 0, + ], + + 'ssh' => [ + 'connection' => 'redis', + 'queue' => ['ssh'], + 'balance' => 'auto', + 'autoScalingStrategy' => 'time', + 'maxProcesses' => 1, + 'maxTime' => 0, + 'maxJobs' => 0, + 'memory' => 128, + 'tries' => 1, + 'timeout' => 600, + 'nice' => 0, + ], + + 'ssh-unique' => [ + 'connection' => 'redis', + 'queue' => ['ssh-unique'], + 'balance' => 'auto', + 'autoScalingStrategy' => 'time', + 'maxProcesses' => 1, + 'maxTime' => 0, + 'maxJobs' => 0, + 'memory' => 128, + 'tries' => 1, + 'timeout' => 600, + 'nice' => 0, + ], + ], + + 'environments' => [ + '*' => [ + 'default' => [ + 'maxProcesses' => 3, + ], + 'ssh' => [ + 'maxProcesses' => 3, + ], + 'ssh-unique' => [ + 'maxProcesses' => 1, + ], + ], + ], +]; diff --git a/docker/supervisord.conf b/docker/supervisord.conf index 86b166ce..62b936c1 100644 --- a/docker/supervisord.conf +++ b/docker/supervisord.conf @@ -10,7 +10,7 @@ user=root autostart=1 autorestart=1 numprocs=1 -command=/usr/bin/php /var/www/html/artisan queue:work --sleep=3 --backoff=0 --queue=default,ssh,ssh-long --timeout=3600 --tries=1 +command=/usr/bin/php /var/www/html/artisan horizon redirect_stderr=true stdout_logfile=/var/www/html/storage/logs/worker.log stopwaitsecs=3600 diff --git a/phpstan.neon b/phpstan.neon index 7a9ce48d..51910f80 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,7 +4,6 @@ includes: parameters: paths: - app - - config - bootstrap - database/factories level: 7 diff --git a/resources/js/components/app-sidebar.tsx b/resources/js/components/app-sidebar.tsx index 3bfda8d1..781662b3 100644 --- a/resources/js/components/app-sidebar.tsx +++ b/resources/js/components/app-sidebar.tsx @@ -14,7 +14,7 @@ import { } from '@/components/ui/sidebar'; import { type NavItem, SharedData } from '@/types'; import { Link, usePage } from '@inertiajs/react'; -import { BookOpen, ChevronRightIcon, CogIcon, Folder, MousePointerClickIcon, ServerIcon, ZapIcon } from 'lucide-react'; +import { BookOpen, ChevronRightIcon, CogIcon, Folder, ListEndIcon, LogsIcon, MousePointerClickIcon, ServerIcon, ZapIcon } from 'lucide-react'; import AppLogo from './app-logo'; import { Icon } from '@/components/icon'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; @@ -44,6 +44,16 @@ const mainNavItems: NavItem[] = [ ]; const footerNavItems: NavItem[] = [ + { + title: 'Workers', + href: route('horizon.index'), + icon: ListEndIcon, + }, + { + title: 'Logs', + href: route('log-viewer.index'), + icon: LogsIcon, + }, { title: 'Repository', href: 'https://github.com/vitodeploy/vito', diff --git a/resources/js/layouts/settings/layout.tsx b/resources/js/layouts/settings/layout.tsx index 5be20b82..0e3dd203 100644 --- a/resources/js/layouts/settings/layout.tsx +++ b/resources/js/layouts/settings/layout.tsx @@ -1,18 +1,5 @@ import { type BreadcrumbItem, type NavItem } from '@/types'; -import { - BellIcon, - CloudIcon, - CodeIcon, - CommandIcon, - DatabaseIcon, - KeyIcon, - ListIcon, - LogsIcon, - PlugIcon, - TagIcon, - UserIcon, - UsersIcon, -} from 'lucide-react'; +import { BellIcon, CloudIcon, CodeIcon, CommandIcon, DatabaseIcon, KeyIcon, ListIcon, PlugIcon, TagIcon, UserIcon, UsersIcon } from 'lucide-react'; import { ReactNode } from 'react'; import Layout from '@/layouts/app/layout'; import VitoIcon from '@/icons/vito'; @@ -78,12 +65,6 @@ const sidebarNavItems: NavItem[] = [ href: route('vito-settings'), icon: VitoIcon, }, - { - title: 'Vito Logs', - href: route('log-viewer.index'), - icon: LogsIcon, - external: true, - }, ]; export default function SettingsLayout({ children, breadcrumbs }: { children: ReactNode; breadcrumbs?: BreadcrumbItem[] }) { diff --git a/scripts/install.sh b/scripts/install.sh index 5ff30187..db0494bc 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -209,7 +209,7 @@ chown -R vito:vito /home/vito export V_WORKER_CONFIG=" [program:worker] process_name=%(program_name)s_%(process_num)02d -command=php /home/vito/vito/artisan queue:work --sleep=3 --backoff=0 --queue=default,ssh,ssh-long --timeout=3600 --tries=1 +command=php /home/vito/vito/artisan horizon autostart=1 autorestart=1 user=vito diff --git a/scripts/upgrade-2x-to-3x.sh b/scripts/upgrade-2x-to-3x.sh index f587c25f..d4aec203 100644 --- a/scripts/upgrade-2x-to-3x.sh +++ b/scripts/upgrade-2x-to-3x.sh @@ -35,6 +35,10 @@ sudo sed -i "s/php8.2-fpm.sock/php8.4-fpm.sock/g" /etc/nginx/sites-available/vit sudo sed -i '/server\s*{.*/a \ client_max_body_size 100M;' /etc/nginx/sites-available/vito sudo service nginx restart +echo "Update supervisor configuration" +sudo sed -i 's/command=php \/home\/vito\/vito\/artisan queue:work --sleep=3 --backoff=0 --queue=default,ssh,ssh-long --timeout=3600 --tries=1/command=php \/home\/vito\/vito\/artisan horizon/' /etc/supervisor/conf.d/worker.conf +sudo service supervisor restart + echo "Fetching the latest release" git fetch git checkout 3.x