first commit
This commit is contained in:
parent
2e3a64ebe4
commit
212ce28396
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "kai/hello-command",
|
||||
"name": "kai/KaiCommand",
|
||||
"type": "laravel-package",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Kai\\HelloCommand\\HelloCommandServiceProvider"
|
||||
"Kai\\KaiCommand\\KaiCommandServiceProvider"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Kai\HelloCommand;
|
||||
namespace Kai\KaiCommand;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class HelloCommandServiceProvider extends ServiceProvider
|
||||
class KaiCommandServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
|
|
@ -25,7 +25,9 @@ class HelloCommandServiceProvider extends ServiceProvider
|
|||
{
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->commands([
|
||||
HelloCommand::class, // Đăng ký Command Class của bạn
|
||||
KaiHelloCommand::class,
|
||||
QueueWorkCommand::class,
|
||||
ScheduleWorkCommand::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Kai\HelloCommand;
|
||||
namespace Kai\KaiCommand;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class HelloCommand extends Command
|
||||
class KaiHelloCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
|
|
@ -12,7 +12,7 @@ class HelloCommand extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'hello:world {name?}';
|
||||
protected $signature = 'KaiHello';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
|
|
@ -28,9 +28,8 @@ class HelloCommand extends Command
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
$name = $this->argument('name') ?? 'World';
|
||||
|
||||
$this->info("Hello, {$name}! This command runs from your package.");
|
||||
$this->info("Hello, Kai! This command runs from your package.");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace Kai\KaiCommand;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class QueueWorkCommand extends Command
|
||||
{
|
||||
protected $signature = 'QueueWork {--workers=3 : Number of workers to run}';
|
||||
protected $description = 'Run multiple artisan queue:work processes, restart them if they exit.';
|
||||
|
||||
public function handle(): never
|
||||
{
|
||||
$workers = (int) $this->option('workers');
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
||||
$this->warn('Killing any existing queue:work processes...');
|
||||
exec('pkill -f "artisan queue:work"');
|
||||
}
|
||||
|
||||
$this->info("Starting {$workers} queue:work processes...");
|
||||
|
||||
$processes = [];
|
||||
$pipesList = [];
|
||||
|
||||
for ($i = 1; $i <= $workers; $i++) {
|
||||
$this->info("Launching worker {$i}...");
|
||||
$descriptors = [
|
||||
1 => ['pipe', 'w'], // stdout
|
||||
2 => ['pipe', 'w'], // stderr
|
||||
];
|
||||
$process = proc_open('php artisan queue:work', $descriptors, $pipes);
|
||||
if (is_resource($process)) {
|
||||
stream_set_blocking($pipes[1], false);
|
||||
stream_set_blocking($pipes[2], false);
|
||||
$processes[$i] = $process;
|
||||
$pipesList[$i] = $pipes;
|
||||
}
|
||||
}
|
||||
|
||||
// Monitor loop
|
||||
while (true) {
|
||||
foreach ($processes as $i => $process) {
|
||||
if (is_resource($process)) {
|
||||
$status = proc_get_status($process);
|
||||
|
||||
// Read stdout
|
||||
$out = stream_get_contents($pipesList[$i][1]);
|
||||
if ($out !== '') {
|
||||
foreach (explode("\n", trim($out)) as $line) {
|
||||
if ($line !== '') {
|
||||
$this->info("[Worker {$i}] " . $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read stderr
|
||||
$err = stream_get_contents($pipesList[$i][2]);
|
||||
if ($err !== '') {
|
||||
foreach (explode("\n", trim($err)) as $line) {
|
||||
if ($line !== '') {
|
||||
$this->error("[Worker {$i}] " . $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restart if stopped
|
||||
if (!$status['running']) {
|
||||
$this->warn("Worker {$i} stopped. Restarting...");
|
||||
proc_close($process);
|
||||
$process = proc_open('php artisan queue:work', [
|
||||
1 => ['pipe', 'w'],
|
||||
2 => ['pipe', 'w'],
|
||||
], $pipes);
|
||||
stream_set_blocking($pipes[1], false);
|
||||
stream_set_blocking($pipes[2], false);
|
||||
$processes[$i] = $process;
|
||||
$pipesList[$i] = $pipes;
|
||||
}
|
||||
}
|
||||
}
|
||||
usleep(200000); // 0.2s pause to avoid busy loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Kai\KaiCommand;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ScheduleWorkCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ScheduleWork';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Run artisan schedule:work, and if it exits, kill and restart it.';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
||||
$this->warn('Killing any existing schedule:work monitor processes using pkill...');
|
||||
exec('pkill -f "schedule:work"');
|
||||
}
|
||||
|
||||
$this->info('Starting schedule:work monitor...');
|
||||
while (true) {
|
||||
$this->warn('Killing any remaining schedule:work processes...');
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
exec('taskkill /IM php.exe /F /FI "WINDOWTITLE eq schedule:work"');
|
||||
} else {
|
||||
exec('pkill -f "artisan schedule:work"');
|
||||
}
|
||||
|
||||
$this->info('Starting: php artisan schedule:work');
|
||||
$process = proc_open(
|
||||
'php artisan schedule:work',
|
||||
[
|
||||
1 => ['pipe', 'w'],
|
||||
2 => ['pipe', 'w'],
|
||||
],
|
||||
$pipes
|
||||
);
|
||||
if (is_resource($process)) {
|
||||
// Read output and error
|
||||
while ($line = fgets($pipes[1])) {
|
||||
$this->line(trim($line));
|
||||
}
|
||||
while ($err = fgets($pipes[2])) {
|
||||
$this->error(trim($err));
|
||||
}
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
$status = proc_get_status($process);
|
||||
$pid = $status['pid'] ?? null;
|
||||
proc_terminate($process);
|
||||
return $pid;
|
||||
} else {
|
||||
$this->error('Failed to start schedule:work process. Retrying in 5 seconds...');
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue