Skip to content

Commit

Permalink
[5.x] Improves console output and fixes Carbon v3 support (#1387)
Browse files Browse the repository at this point in the history
* Deprecates Laravel 8, PHP 7.3 and PHP 7.4

* Improves output of `clear` command

* Improves output of `clear:metrics` command

* Improves output of `continue` command

* Improves output of `supervisor:continue` command

* Improves output of `forget:failed` command

* Improves output of `horizon` command

* Improves output of `install` command

* Improves output of `list` command

* Improves output of `timeout` command

* Improves output of `supervisors` command

* Improves output of `supervisor` command

* Improves output of `status` command

* Improves output of `snapshot` command

* Improves output of `supervisor:pause` command

* Improves output of `pause` command

* Improves output of `terminate` command

* Improves output of `purge` command

* Fixes adding seconds to process `terminatedAt`

* Update TimeoutCommand.php

* Update PurgeCommand.php

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
nunomaduro and taylorotwell committed Feb 12, 2024
1 parent e62a24a commit 0b1bf46
Show file tree
Hide file tree
Showing 20 changed files with 113 additions and 83 deletions.
16 changes: 2 additions & 14 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,9 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [7.3, 7.4, '8.0', 8.1, 8.2, 8.3]
laravel: [8, 9, 10, 11]
php: ['8.0', 8.1, 8.2, 8.3]
laravel: [9, 10, 11]
exclude:
- php: 7.3
laravel: 9
- php: 7.3
laravel: 10
- php: 7.3
laravel: 11
- php: 7.4
laravel: 9
- php: 7.4
laravel: 10
- php: 7.4
laravel: 11
- php: '8.0'
laravel: 10
- php: '8.0'
Expand Down
14 changes: 7 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@
}
],
"require": {
"php": "^7.3|^8.0",
"php": "^8.0",
"ext-json": "*",
"ext-pcntl": "*",
"ext-posix": "*",
"illuminate/contracts": "^8.17|^9.0|^10.0|^11.0",
"illuminate/queue": "^8.17|^9.0|^10.0|^11.0",
"illuminate/support": "^8.17|^9.0|^10.0|^11.0",
"illuminate/contracts": "^9.21|^10.0|^11.0",
"illuminate/queue": "^9.21|^10.0|^11.0",
"illuminate/support": "^9.21|^10.0|^11.0",
"nesbot/carbon": "^2.17|^3.0",
"ramsey/uuid": "^4.0",
"symfony/process": "^5.0|^6.0|^7.0",
"symfony/error-handler": "^5.0|^6.0|^7.0"
"symfony/process": "^6.0|^7.0",
"symfony/error-handler": "^6.0|^7.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^6.0|^7.0|^8.0|^9.0",
"orchestra/testbench": "^7.0|^8.0|^9.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.0|^10.4",
"predis/predis": "^1.1|^2.0"
Expand Down
4 changes: 2 additions & 2 deletions src/Console/ClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function handle(JobRepository $jobRepository, QueueManager $manager)
}

if (! method_exists(RedisQueue::class, 'clear')) {
$this->line('<error>Clearing queues is not supported on this version of Laravel</error>');
$this->components->error('Clearing queues is not supported on this version of Laravel.');

return 1;
}
Expand All @@ -54,7 +54,7 @@ public function handle(JobRepository $jobRepository, QueueManager $manager)

$count = $manager->connection($connection)->clear($queue);

$this->line('<info>Cleared '.$count.' jobs from the ['.$queue.'] queue</info> ');
$this->components->info('Cleared '.$count.' jobs from the ['.$queue.'] queue.');

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Console/ClearMetricsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ public function handle(MetricsRepository $metrics)
{
$metrics->clear();

$this->info('Metrics cleared successfully.');
$this->components->info('Metrics cleared successfully.');
}
}
19 changes: 13 additions & 6 deletions src/Console/ContinueCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,19 @@ public function handle(MasterSupervisorRepository $masters)
return Str::startsWith($master->name, MasterSupervisor::basename());
})->all();

foreach (Arr::pluck($masters, 'pid') as $processId) {
$this->info("Sending CONT Signal To Process: {$processId}");
collect(Arr::pluck($masters, 'pid'))
->whenNotEmpty(fn () => $this->components->info('Sending CONT signal to processes.'))
->whenEmpty(fn () => $this->components->info('No processes to continue.'))
->each(function ($processId) {
$result = true;

if (! posix_kill($processId, SIGCONT)) {
$this->error("Failed to kill process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
}
$this->components->task("Process: $processId", function () use ($processId, &$result) {
return $result = posix_kill($processId, SIGCONT);
});

if (! $result) {
$this->components->error("Failed to kill process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
})->whenNotEmpty(fn () => $this->output->writeln(''));
}
}
6 changes: 3 additions & 3 deletions src/Console/ContinueSupervisorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ public function handle(SupervisorRepository $supervisors)
}))->pid;

if (is_null($processId)) {
$this->error('Failed to find a supervisor with this name');
$this->components->error('Failed to find a supervisor with this name');

return 1;
}

$this->info("Sending CONT Signal To Process: {$processId}");
$this->components->info("Sending CONT signal to process: {$processId}");

if (! posix_kill($processId, SIGCONT)) {
$this->error("Failed to send CONT signal to process: {$processId} (".posix_strerror(posix_get_last_error()).')');
$this->components->error("Failed to send CONT signal to process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
}
}
4 changes: 2 additions & 2 deletions src/Console/ForgetFailedCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ public function handle(JobRepository $repository)
$repository->deleteFailed($this->argument('id'));

if ($this->laravel['queue.failer']->forget($this->argument('id'))) {
$this->info('Failed job deleted successfully!');
$this->components->info('Failed job deleted successfully!');
} else {
$this->error('No failed job matches the given ID.');
$this->components->error('No failed job matches the given ID.');

return 1;
}
Expand Down
8 changes: 5 additions & 3 deletions src/Console/HorizonCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class HorizonCommand extends Command
public function handle(MasterSupervisorRepository $masters)
{
if ($masters->find(MasterSupervisor::name())) {
return $this->comment('A master supervisor is already running on this machine.');
return $this->components->warn('A master supervisor is already running on this machine.');
}

$environment = $this->option('environment') ?? config('horizon.env') ?? config('app.env');
Expand All @@ -43,12 +43,14 @@ public function handle(MasterSupervisorRepository $masters)

ProvisioningPlan::get(MasterSupervisor::name())->deploy($environment);

$this->info('Horizon started successfully.');
$this->components->info('Horizon started successfully.');

pcntl_async_signals(true);

pcntl_signal(SIGINT, function () use ($master) {
$this->line('Shutting down...');
$this->output->writeln('');

$this->components->info('Shutting down.');

return $master->terminate();
});
Expand Down
15 changes: 7 additions & 8 deletions src/Console/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,17 @@ class InstallCommand extends Command
*/
public function handle()
{
$this->comment('Publishing Horizon Service Provider...');
$this->callSilent('vendor:publish', ['--tag' => 'horizon-provider']);
$this->components->info('Installing Horizon resources.');

$this->comment('Publishing Horizon Assets...');
$this->callSilent('vendor:publish', ['--tag' => 'horizon-assets']);

$this->comment('Publishing Horizon Configuration...');
$this->callSilent('vendor:publish', ['--tag' => 'horizon-config']);
collect([
'Assets' => fn () => $this->callSilent('vendor:publish', ['--tag' => 'horizon-assets']) == 0,
'Service Provider' => fn () => $this->callSilent('vendor:publish', ['--tag' => 'horizon-provider']) == 0,
'Configuration' => fn () => $this->callSilent('vendor:publish', ['--tag' => 'horizon-config']) == 0,
])->each(fn ($task, $description) => $this->components->task($description, $task));

$this->registerHorizonServiceProvider();

$this->info('Horizon scaffolding installed successfully.');
$this->components->info('Horizon scaffolding installed successfully.');
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/Console/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ public function handle(MasterSupervisorRepository $masters)
$masters = $masters->all();

if (empty($masters)) {
return $this->info('No machines are running.');
return $this->components->info('No machines are running.');
}

$this->output->writeln('');

$this->table([
'Name', 'PID', 'Supervisors', 'Status',
], collect($masters)->map(function ($master) {
Expand All @@ -47,5 +49,7 @@ public function handle(MasterSupervisorRepository $masters)
$master->status,
];
})->all());

$this->output->writeln('');
}
}
19 changes: 13 additions & 6 deletions src/Console/PauseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,19 @@ public function handle(MasterSupervisorRepository $masters)
return Str::startsWith($master->name, MasterSupervisor::basename());
})->all();

foreach (Arr::pluck($masters, 'pid') as $processId) {
$this->info("Sending USR2 Signal To Process: {$processId}");
collect(Arr::pluck($masters, 'pid'))
->whenNotEmpty(fn () => $this->components->info('Sending USR2 signal to processes.'))
->whenEmpty(fn () => $this->components->info('No processes to pause.'))
->each(function ($processId) {
$result = true;

if (! posix_kill($processId, SIGUSR2)) {
$this->error("Failed to kill process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
}
$this->components->task("Process: $processId", function () use ($processId, &$result) {
return $result = posix_kill($processId, SIGUSR2);
});

if (! $result) {
$this->components->error("Failed to kill process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
})->whenNotEmpty(fn () => $this->output->writeln(''));
}
}
6 changes: 3 additions & 3 deletions src/Console/PauseSupervisorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ public function handle(SupervisorRepository $supervisors)
}))->pid;

if (is_null($processId)) {
$this->error('Failed to find a supervisor with this name');
$this->components->error('Failed to find a supervisor with this name');

return 1;
}

$this->info("Sending USR2 Signal To Process: {$processId}");
$this->components->info("Sending USR2 signal to process: {$processId}");

if (! posix_kill($processId, SIGUSR2)) {
$this->error("Failed to send USR2 signal to process: {$processId} (".posix_strerror(posix_get_last_error()).')');
$this->components->error("Failed to send USR2 signal to process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
}
}
34 changes: 21 additions & 13 deletions src/Console/PurgeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ public function purge($master, $signal = SIGTERM)
$master, $this->supervisors->longestActiveTimeout()
);

collect($expired)->each(function ($processId) use ($master, $signal) {
$this->comment("Killing Process: {$processId}");

exec("kill -s {$signal} {$processId}");

$this->processes->forgetOrphans($master, [$processId]);
});
collect($expired)
->whenNotEmpty(fn () => $this->components->info('Sending TERM signal to expired processes of ['.$master.']'))
->each(function ($processId) use ($master, $signal) {
$this->components->task("Process: $processId", function () use ($processId, $signal) {
exec("kill -s {$signal} {$processId}");
});

$this->processes->forgetOrphans($master, [$processId]);
})->whenNotEmpty(fn () => $this->output->writeln(''));
}

/**
Expand All @@ -118,12 +120,18 @@ protected function recordOrphans($master, $signal)
$master, $orphans = $this->inspector->orphaned()
);

foreach ($orphans as $processId) {
$this->info("Observed Orphan: {$processId}");
collect($orphans)
->whenNotEmpty(fn () => $this->components->info('Sending TERM signal to orphaned processes of ['.$master.']'))
->each(function ($processId) use ($signal) {
$result = true;

if (! posix_kill($processId, $signal)) {
$this->error("Failed to kill process for Orphan: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
}
$this->components->task("Process: $processId", function () use ($processId, $signal, &$result) {
return $result = posix_kill($processId, $signal);
});

if (! $result) {
$this->components->error("Failed to kill orphan process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
})->whenNotEmpty(fn () => $this->output->writeln(''));
}
}
2 changes: 1 addition & 1 deletion src/Console/SnapshotCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function handle(Lock $lock, MetricsRepository $metrics)
if ($lock->get('metrics:snapshot', config('horizon.metrics.snapshot_lock', 300) - 30)) {
$metrics->snapshot();

$this->info('Metrics snapshot stored successfully.');
$this->components->info('Metrics snapshot stored successfully.');
}
}
}
6 changes: 3 additions & 3 deletions src/Console/StatusCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ class StatusCommand extends Command
public function handle(MasterSupervisorRepository $masterSupervisorRepository)
{
if (! $masters = $masterSupervisorRepository->all()) {
$this->error('Horizon is inactive.');
$this->components->error('Horizon is inactive.');

return 1;
}

if (collect($masters)->contains(function ($master) {
return $master->status === 'paused';
})) {
$this->warn('Horizon is paused.');
$this->components->warn('Horizon is paused.');

return 1;
}

$this->info('Horizon is running.');
$this->components->info('Horizon is running.');

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Console/SupervisorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function handle(SupervisorFactory $factory)
try {
$supervisor->ensureNoDuplicateSupervisors();
} catch (Exception $e) {
$this->error('A supervisor with this name is already running.');
$this->components->error('A supervisor with this name is already running.');

return 13;
}
Expand Down
6 changes: 5 additions & 1 deletion src/Console/SupervisorsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ public function handle(SupervisorRepository $supervisors)
$supervisors = $supervisors->all();

if (empty($supervisors)) {
return $this->info('No supervisors are running.');
return $this->components->info('No supervisors are running.');
}

$this->output->writeln('');

$this->table([
'Name', 'PID', 'Status', 'Workers', 'Balancing',
], collect($supervisors)->map(function ($supervisor) {
Expand All @@ -48,5 +50,7 @@ public function handle(SupervisorRepository $supervisors)
$supervisor->options['balance'],
];
})->all());

$this->output->writeln('');
}
}
19 changes: 13 additions & 6 deletions src/Console/TerminateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,20 @@ public function handle(CacheFactory $cache, MasterSupervisorRepository $masters)
return Str::startsWith($master->name, MasterSupervisor::basename());
})->all();

foreach (Arr::pluck($masters, 'pid') as $processId) {
$this->info("Sending TERM Signal To Process: {$processId}");
collect(Arr::pluck($masters, 'pid'))
->whenNotEmpty(fn () => $this->components->info('Sending TERM signal to processes.'))
->whenEmpty(fn () => $this->components->info('No processes to terminate.'))
->each(function ($processId) {
$result = true;

if (! posix_kill($processId, SIGTERM)) {
$this->error("Failed to kill process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
}
$this->components->task("Process: $processId", function () use ($processId, &$result) {
return $result = posix_kill($processId, SIGTERM);
});

if (! $result) {
$this->components->error("Failed to kill process: {$processId} (".posix_strerror(posix_get_last_error()).')');
}
})->whenNotEmpty(fn () => $this->output->writeln(''));

$this->laravel['cache']->forever('illuminate:queue:restart', $this->currentTime());
}
Expand Down

0 comments on commit 0b1bf46

Please sign in to comment.