su/child-process

提供子进程管理模块

1.1.2 2023-07-07 04:37 UTC

This package is auto-updated.

Last update: 2024-09-07 07:02:02 UTC


README

提供基于sue/event-loop的子进程管理工具,需要php >= 5.6.0即可

什么是ReactPHP?

ReactPHP是一款基于PHP的事件驱动的组件。核心是提供EventLoop,然后提供基于EventLoop上的各种组件,比如I/O处理,定时器等。

进程

\Sue\ChildProcess\Process 为普通进程,拥有最大运行时间,超过时间会被终止,默认最大运行时间1800秒

use Sue\ChildProcess\Process;

use function Sue\EventLoop\loop;

$process = new Process('php demo.php');
$process->attach();
loop()->run();

setMaxRunningSeconds

$process->setMaxRunningSeconds(3600)可以为进程设置最大运行时间(在进程启动后也可调整), 如果超出运行时间则会抛出rejected promise

use Sue\ChildProcess\Process;
use Sue\ChildProcess\Exceptions\TimeoutException;

use function Sue\EventLoop\loop;

$process = new Process('php demo.php');
$process->setMaxRunningSeconds(15);
$process->attach()
    ->then(
        function () {
            echo "process executed successfully\n";
        },
        function (TimeoutException $e) {
            echo "超时: " . $e;
        }
    );
loop()->run();

PersistentProcess

\Sue\ChildProcess\PersistentProcess为常驻进程。拥有最小运行时间以及最大重试次数,默认最小运行时间为1秒,默认最大重试次数为10次。 规则是如果进程持续时间小于1秒,则累积重试次数,反之则重置重试次数; 当重试次数超过最大则抛弃rejected promise

use Sue\ChildProcess\PersistentProcess;
use Sue\ChildProcess\Exceptions\ProcessException;

use function Sue\EventLoop\loop;

$process = new PersistentProcess('php consumer.php');
$process->attach()
    ->otherwise(function (ProcessException $exception) {
        echo "fail to start process\n";
    });
loop()->run();

setMaxRetries

$process->setMaxRetries(15)可以设置最大重启次数

setMinUpTime

$process->setMinUpTime(3.14)可以设置进程最小存活时间

use Sue\ChildProcess\PersistentProcess;

use function Sue\EventLoop\loop;

$process = new PersistentProcess('php consumer.php');
$process->setMinUpTime(2.15)
    ->setMaxRetries(15)
    ->attach()
    ->then(
        function () {
            echo "process exited successfully\n";
        },
        function ($error) {
            echo $error . "\n";
        }
    );
loop()->run();

AbstractProcess

AbstractProcess是由ProcessPersistentProcess继承的基础类

attach

在AbstractProcess对象生成后需要用$process->attach()方法将进程挂载到eventloop上,这样子进程才会启动

$process = new PersistentProcess('php consumer.php');
$process->attach();
loop()->run();

promise

获取进程运行结果的promise

$process = new Process('php work.php');
$process->attach();
$process->promise()->then(
    function () {
        echo "process end successfully\n"
    },
    function ($error) {
        echo "process stop with error: " . $error . "\n";
    }
);

terminate

$process->terminate($signal, $exception)可以中止正在运行的进程

use Sue\ChildProcess\PersistentProcess;

use function Sue\EventLoop\loop;
use function Sue\EventLoop\setInterval;

$time_start = time();
$process = new PersistentProcess('php consumer.php');
setInterval(1, function () use ($process, $time_start) {
    if (time() - $time_start > 30) {
        $process->terminate();
    }
});
$process->attach();
loop()->run();

如果$process->terminate(null, $exception)则这个exception会传递到attach返回的promise中

$process = new PersistentProcess('php consumer.php');
setInterval(1, function () use ($process, $time_start) {
    if (time() - $time_start > 30) {
        $process->terminate(null, new \RuntimeException('foo'));
    }
});
$process->attach()->then(null, function (\RuntimeException $e) {
    //error handle
});

output

$process->output()可以为进程注册一个回调函数,用以实时接收进程的stdout的输出信息。

这个功能在windows的命令行环境中无法使用(方法不报错,但是不会接收到任何数据) windows平台可以在 WSL (windows sub linux) 中正常使用

//consumer.php
while (true) {
    echo "hello world\n";
    sleep(1);
}

//process.php
use Sue\ChildProcess\PersistentProcess;
use function Sue\EventLoop\loop;

$process = new PersistentProcess('php consumer.php');
$process->output(function ($chunk) {
    echo $chunk;
});
$process->attach();
loop()->run();
/** expected output:
 * hello world
 * hello world
 * hello world
 * hello world
 * ...
 */

errorOutput

$process->errorOutput()可以为进程注册一个回调函数,用以实时接收进程的stderr的输出信息。

这个功能在windows的命令行环境中无法使用(方法不报错,但是不会接收到任何数据) windows平台可以在 WSL (windows sub linux) 中正常使用

//consumer.php
while (true) {
    echo "hello world\n";
    sleep(1);
}
throw new Exception('foo');

//process.php
use Sue\ChildProcess\Process;
use function Sue\EventLoop\loop;
$process = new Process('php consumer.php');
$process->errorOutput(function ($chunk) {
    echo $chunk;
});
$process->attach();
loop()->run();
/** expected output:
* Fatal error: Uncaught Exception: foo in consumer.php:3
 */

isRunning

$process->isRunning()可以检测进程是否正在运行

use Sue\ChildProcess\PersistentProcess;

use function Sue\EventLoop\loop;
use function Sue\EventLoop\setInterval;
use function Sue\EventLoop\cancelTimer;

$process = new PersistentProcess('php consumer.php');
setInterval(5, function ($timer) use ($process) {
    if ($process->isRunning()) {
        echo "process looks good\n";
    } else {
        echo "process went wrong\n";
        cancelTimer($timer);
    }
});

isStopped

$process->isStopped()检测进程是否已停止

install

$ composer require sue/child-process 使用composer安装组件

tests

$ composer install
$ ./vendor/bin/phpunit

许可证

The MIT License (MIT)

版权所有 (c) 2023 张东海

任何人都可以免费获得此软件及其相关文档副本(“软件”),并可在不受限制的情况下使用该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许向获得软件的人提供上述权限,前提是必须遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和无侵权性。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论此类责任基于合同、侵权或其他方式,均与软件或软件的使用或任何其他交易有关。