nusje2000 / process-runner
一个简单的PHP进程内运行多个进程的包。
Requires
- php: ^7.2 || ^8.0
- ramsey/uuid: ^4.1
- symfony/console: ^4.4|^5.0|^6.0
- symfony/process: ^4.4|^5.0|^6.0
Requires (Dev)
- phpstan/phpstan: ^0.12.32
- phpstan/phpstan-symfony: ^0.12.6
- phpunit/phpunit: ^8.5
- vimeo/psalm: ^4.4
README
此包提供在PHP进程内运行命令的简单服务。每套命令称为一个 TaskList
,每个TaskList包含一系列任务。一个 TaskList
可以通过一个 Executor
处理,该执行器从每个任务中获取命令并运行。
创建 TaskList
可以通过以下方式手动创建任务列表
use Nusje2000\ProcessRunner\Task; use Nusje2000\ProcessRunner\TaskList; use Symfony\Component\Process\Process; $list = new TaskList([ new Task('task name', new Process(['some-command'])), new Task('task name', new Process(['some-other-command'])), ]);
或者使用提供的简单任务列表工厂
use Nusje2000\ProcessRunner\Factory\TaskListFactory; $list = TaskListFactory::createFromArray([ 'task name' => 'command argument --option' ]);
执行 TaskList
命令的执行由一个执行器完成,此包提供了两个执行器:ParallelExecutor 和 SequentialExecutor。
您可以通过运行 php vendor/nusje2000/process-runner/bin/example.php
来尝试它们。这将使用顺序和并行执行器运行一系列命令。
使用并行执行器
ParallelExecutor 同时运行所有任务。
use Nusje2000\ProcessRunner\Executor\ParallelExecutor; use Nusje2000\ProcessRunner\TaskList; $executor = new ParallelExecutor(); $executor->execute(new TaskList([]));
使用顺序执行器
SequentialExecutor 在每个任务之后运行所有任务。
use Nusje2000\ProcessRunner\Executor\SequentialExecutor; use Nusje2000\ProcessRunner\TaskList; $executor = new SequentialExecutor(); $executor->execute(new TaskList([]));
监听进程更新
有时必须将命令的输出用于父进程。这可以通过使用监听器来实现。每个监听器都有一个 onTick 函数,当检查子进程状态时被调用。
使用回调监听器创建监听器
如果您想向执行器添加一个简单的监听函数,则可以使用 CallbackListener。它接受一个回调作为参数,然后使用该回调作为 tick 函数。
use Nusje2000\ProcessRunner\Executor\ExecutorInterface; use Nusje2000\ProcessRunner\Listener\CallbackListener; use Nusje2000\ProcessRunner\TaskList; $listener = new CallbackListener(static function (TaskList $taskList) { echo sprintf('There are %d running tasks.', $taskList->getRunningTasks()->count()); }); /** @var ExecutorInterface $executor */ $executor->addListener($listener);
使用 ExecutionListener 接口创建监听器
有时监听器对于简单的回调函数来说太复杂了,在这种情况下,您可以创建自己的类来实现 ExecutionListener 接口以处理 tick。
use Nusje2000\ProcessRunner\Executor\ExecutorInterface; use Nusje2000\ProcessRunner\Listener\ExecutionListener; use Nusje2000\ProcessRunner\TaskList; class RunningTaskListener implements ExecutionListener { public function onTick(TaskList $taskList) : void { echo sprintf('There are %d running tasks.', $taskList->getRunningTasks()->count()); } public function getPriority() : int{ return 0; } } /** @var ExecutorInterface $executor */ $executor->addListener(new RunningTaskListener());
将任务状态转发到控制台
在大多数情况下,父进程也是一个命令。如果您想看到子进程的状态在父进程的输出中,可以向执行器添加 ConsoleListener。这将显示所有任务及其状态,并在出错的情况下显示子进程的输出和错误输出。
use Nusje2000\ProcessRunner\Executor\ExecutorInterface; use Nusje2000\ProcessRunner\Listener\ConsoleListener; use Symfony\Component\Console\Output\ConsoleOutput; /** @var ExecutorInterface $executor */ $executor->addListener(new ConsoleListener(new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, true)));
监听器的输出将如下所示
echo "Hello world!" (success)
process name 1 (success)
process name 2 (success)
process name 3 (failed (exit code: 255))
Task "process name 3" failed (exit code: 255).
Error output:
PHP Fatal error: Uncaught Exception: error in Command line code:1
Stack trace:
#0 {main}
thrown in Command line code on line 1
在输出记录的情况下使用控制台监听器
在某些情况下(例如 CI/CD 集成),控制台命令的输出被记录到文件中。如果这种情况成立,使用默认的 ConsoleLogger 将会导致每个进程状态更改检查(默认每秒5次)的输出。对于这些用例,您可以使用 StaticConsoleListener。此监听器将只打印更改到控制台,而不是使用部分更新控制台输出。
use Nusje2000\ProcessRunner\Executor\ExecutorInterface; use Nusje2000\ProcessRunner\Listener\StaticConsoleListener; use Symfony\Component\Console\Output\ConsoleOutput; /** @var ExecutorInterface $executor */ $executor->addListener(new StaticConsoleListener(new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, true)));
监听器的输出将如下所示
echo "Hello world!" is running
echo "Hello world!" is successfull
process name 1 is running
process name 1 is successfull
process name 2 is running
process name 2 is successfull
process name 3 is running
process name 3 has failed
Error output:
PHP Fatal error: Uncaught Exception: Some exception message in Command line code:1
Stack trace:
#0 {main}
thrown in Command line code on line 1