Ver código fonte

feat(worker): 添加 Workerman 服务管理命令支持

- 增加了 action 参数支持 start|stop|restart|reload|status|connections 操作
- 添加了 daemon 和 grace 选项用于后台运行和优雅关闭
- 实现了手动信号处理机制控制 Worker 进程
- 集成了 PID 文件管理和进程状态检测功能
- 支持优雅重启和强制重启两种模式
- 保留了原有的环境检测和 DDEV 集成特性
runphp 2 dias atrás
pai
commit
0177078759
1 arquivos alterados com 29 adições e 0 exclusões
  1. 29 0
      src/Command/WorkerCommand.php

+ 29 - 0
src/Command/WorkerCommand.php

@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SixShop\System\Command;
 
+use think\console\input\Argument;
+use think\console\input\Option;
 use think\worker\command\Server;
 use think\worker\Manager;
 
@@ -12,11 +14,38 @@ class WorkerCommand extends Server
     public function configure(): void
     {
         $this->setName('system:worker')
+            ->addArgument('action', Argument::OPTIONAL, 'start|stop|restart|reload|status|connections', 'start')
+            ->addOption('daemon', 'd', Option::VALUE_NONE, 'daemon mode')
+            ->addOption('grace', 'g', Option::VALUE_NONE, 'graceful shutdown/reload')
             ->setDescription('Workerman Server for ThinkPHP (with env detection)');
     }
 
     public function handle(Manager $manager)
     {
+        $action  = $this->input->getArgument('action') ?: 'start';
+        $grace   = $this->input->getOption('grace');
+
+        // think\worker\Worker 禁用了 parseCommand(),需手动处理控制命令
+        if ($action !== 'start') {
+            $pidFile = runtime_path() . 'worker.pid';
+            $masterPid = is_file($pidFile) ? (int) file_get_contents($pidFile) : 0;
+
+            if ($masterPid <= 0 || !posix_kill($masterPid, 0)) {
+                $this->output->error('Worker is not running');
+                return;
+            }
+
+            match ($action) {
+                'stop'  => posix_kill($masterPid, $grace ? SIGQUIT : SIGINT),
+                'reload' => posix_kill($masterPid, $grace ? SIGUSR2 : SIGUSR1),
+                'restart' => posix_kill($masterPid, $grace ? SIGQUIT : SIGINT),
+                default  => null,
+            };
+
+            $this->output->info("Worker {$action} signal sent");
+            return;
+        }
+
         $envName = getenv('RUNTIME_ENVIRONMENT') ?: '';
         if (getenv('IS_DDEV_PROJECT') == 'true') {
             $envName = 'ddev';