From 212ce283969577d4ccd36d52ae80ce13f969fdc1 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 22 Oct 2025 06:02:24 +0000 Subject: [PATCH] first commit --- composer.json | 4 +- ...ider.php => KaiCommandServiceProvider.php} | 8 +- src/{HelloCommand.php => KaiHelloCommand.php} | 9 +- src/QueueWorkCommand.php | 85 +++++++++++++++++++ src/ScheduleWorkCommand.php | 68 +++++++++++++++ 5 files changed, 164 insertions(+), 10 deletions(-) rename src/{HelloCommandServiceProvider.php => KaiCommandServiceProvider.php} (66%) rename src/{HelloCommand.php => KaiHelloCommand.php} (67%) create mode 100644 src/QueueWorkCommand.php create mode 100644 src/ScheduleWorkCommand.php diff --git a/composer.json b/composer.json index b6e271c..a6928fd 100644 --- a/composer.json +++ b/composer.json @@ -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" ] } } diff --git a/src/HelloCommandServiceProvider.php b/src/KaiCommandServiceProvider.php similarity index 66% rename from src/HelloCommandServiceProvider.php rename to src/KaiCommandServiceProvider.php index edf31b6..32fd18f 100644 --- a/src/HelloCommandServiceProvider.php +++ b/src/KaiCommandServiceProvider.php @@ -1,10 +1,10 @@ app->runningInConsole()) { $this->commands([ - HelloCommand::class, // Đăng ký Command Class của bạn + KaiHelloCommand::class, + QueueWorkCommand::class, + ScheduleWorkCommand::class ]); } } diff --git a/src/HelloCommand.php b/src/KaiHelloCommand.php similarity index 67% rename from src/HelloCommand.php rename to src/KaiHelloCommand.php index 29e617b..caf93db 100644 --- a/src/HelloCommand.php +++ b/src/KaiHelloCommand.php @@ -1,10 +1,10 @@ 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; } diff --git a/src/QueueWorkCommand.php b/src/QueueWorkCommand.php new file mode 100644 index 0000000..de1b506 --- /dev/null +++ b/src/QueueWorkCommand.php @@ -0,0 +1,85 @@ +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 + } + } +} \ No newline at end of file diff --git a/src/ScheduleWorkCommand.php b/src/ScheduleWorkCommand.php new file mode 100644 index 0000000..ac81210 --- /dev/null +++ b/src/ScheduleWorkCommand.php @@ -0,0 +1,68 @@ +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); + } + } + } +}