symplely/processor

此包已被弃用且不再维护。作者建议使用 symplely/spawn 包。

一个提供并行和异步 PHP 的 Symfony 进程管理器,用于处理阻塞 I/O。

1.4.3 2020-03-03 01:21 UTC

This package is auto-updated.

Last update: 2020-04-06 19:48:31 UTC


README

Build StatusBuild statuscodecovCodacy BadgeMaintainability

一个为 symfony/process 创建的简单 进程管理器 包装 API,用于 执行管理 子进程

它是 pcntl-extension 的替代品,当未安装时。这是我们的 symplely/coroutine 包的一部分,用于处理任何 阻塞 I/O 进程,这些进程不是由原生 协程 处理的。

该库旨在为 Windows OS 和其他系统提供一个易于使用的 API 来控制/管理子进程,而无需安装任何额外的软件扩展。

安装

composer require symplely/processor

用法

include 'vendor/autoload.php';

use Async\Processor\Processor;

// To set the path to PHP executable for child process
Processor::phpPath('/some/path/version-7.3/bin/php');

$process = \spawn($function, $timeout, $channel)
// Or
$process = Processor::create(function () use ($thing) {
    // Do a thing
    }, $timeout, $channel)
    ->then(function ($output) {
        // Handle success
    })->catch(function (\Throwable $exception) {
        // Handle exception
});

\spawn_run($process);
// Or
$process->run();

// Second option can be used to set to display child output, default is false
\spawn_run($process, true);
// Or
$process->displayOn()->run();

通道 - 在进程间传输消息

include 'vendor/autoload.php';

use Async\Processor\Channel;
use Async\Processor\ChannelInterface;

$ipc = new Channel();

$process = spawn(function (ChannelInterface $channel) {
    $channel->write('ping'); // same as echo 'ping' or echo fwrite(STDOUT, 'ping')
    usleep(1000);
    echo $channel->read(); // same as echo fgets(STDIN);
    echo $channel->read();
    usleep(1000);
    return 'return whatever';
    }, 300, $ipc)
        ->progress(function ($type, $data) use ($ipc) {
            if ('ping' === $data) {
                $ipc->send('pang' . \PHP_EOL);
            } elseif (!$ipc->isClosed()) {
                $ipc->send('pong' . \PHP_EOL);
                    ->close();
            }
        });

$ipc->setup($process)
\spawn_run($process);

echo \spawn_output($process); // pingpangpongreturn whatever
// Or
echo $ipc->receive(); // return whatever

事件钩子

创建异步进程时,将返回一个 LauncherInterface 实例。您可以在进程上添加以下事件钩子。

$process = spawn($function, $timeout, $channel)
// Or
$process = Processor::create(function () {
        // The second argument is optional, Defaults 300.
        // it sets The maximum amount of time a process may take to finish in seconds
        // The third is optional input pipe to pass to subprocess
    }, int $timeout = 300 , $input = null)
    ->then(function ($output) {
        // On success, `$output` is returned by the process.
    })
    ->catch(function ($exception) {
        // When an exception is thrown from within a process, it's caught and passed here.
    })
    ->timeout(function () {
        // When an time is reached, it's caught and passed here.
    })
    ->progress(function ($type, $data) {
        // A IPC like gateway: `$type, $data` is returned by the process progressing, it's producing output.
        // This can be use as a IPC handler for real time interaction.
    });

还包括 ->done,它是 ->then() 扩展回调方法的一部分。

->done(function ($result) {
    // On success, `$result` is returned by the process or callable you passed to the queue.
});
->then(function ($resultOutput) {
        //
    }, function ($catchException) {
        //
    }, function ($progressOutput) {
        //
    }
);

// To turn on to display child output.
->displayOn();

// Stop displaying child output.
->displayOff();

// To display child output, only by third party means once turned on.
->display();

// Processes can be retried.
->restart();
->run();

错误处理

如果子进程中抛出了 ExceptionError,可以通过在 ->catch() 方法中指定回调来按进程捕获。

如果没有添加错误处理器,则在调用 spawn_run()$process->run() 时,错误将在父进程中抛出。

如果子进程意外停止而没有抛出 Throwable,则写入 stderr 的输出将被包装并作为父进程中的 Async\Processor\ProcessorError 抛出。

贡献

鼓励贡献,欢迎;我总是很高兴在 Github 上收到反馈或拉取请求 :) 为错误和新功能创建 Github 问题 并评论您感兴趣的问题。

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件