nusje2000/process-runner

一个简单的PHP进程内运行多个进程的包。

v1.1.0 2022-10-03 11:14 UTC

This package is auto-updated.

Last update: 2024-08-30 01:43:53 UTC


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