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",
|
"type": "laravel-package",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"extra": {
|
"extra": {
|
||||||
"laravel": {
|
"laravel": {
|
||||||
"providers": [
|
"providers": [
|
||||||
"Kai\\HelloCommand\\HelloCommandServiceProvider"
|
"Kai\\KaiCommand\\KaiCommandServiceProvider"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kai\HelloCommand;
|
namespace Kai\KaiCommand;
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class HelloCommandServiceProvider extends ServiceProvider
|
class KaiCommandServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Register any application services.
|
* Register any application services.
|
||||||
|
|
@ -25,7 +25,9 @@ class HelloCommandServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->commands([
|
$this->commands([
|
||||||
HelloCommand::class, // Đăng ký Command Class của bạn
|
KaiHelloCommand::class,
|
||||||
|
QueueWorkCommand::class,
|
||||||
|
ScheduleWorkCommand::class
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Kai\HelloCommand;
|
namespace Kai\KaiCommand;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class HelloCommand extends Command
|
class KaiHelloCommand extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The name and signature of the console command.
|
* The name and signature of the console command.
|
||||||
|
|
@ -12,7 +12,7 @@ class HelloCommand extends Command
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'hello:world {name?}';
|
protected $signature = 'KaiHello';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
|
|
@ -28,9 +28,8 @@ class HelloCommand extends Command
|
||||||
*/
|
*/
|
||||||
public function handle()
|
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;
|
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