justmisha/php-multirunner

该包提供了在后台并行运行多个进程(程序和脚本)的能力。

0.9.0 2024-09-29 18:11 UTC

This package is auto-updated.

Last update: 2024-09-29 18:14:25 UTC


README

ru

PHP MultiRunner

一个用于在后台并行运行多个进程并,如果需要,获取其工作结果的包。

显然,首先,这种并行执行可以极大地减少所有这些进程的时间。

本包

  • 具有非常简单的接口;
  • 可以运行系统上安装了解释器的任何程序、脚本或代码;
  • 适用于Windows和Linux;
  • 允许在进程和您的代码之间传输大量数据 - 测试证实约为2Mb。

底层,它使用proc_open()启动进程,并隐藏了PHP中处理进程的许多复杂性和特殊性。

不需要安装任何其他包或扩展。

使用方法

运行多个具有不同参数的PHP脚本,并获取其输出消息。

<?php

    use \JustMisha\MultiRunner\ScriptMultiRunner;

    $maxParallelProcesses = 512;    //  determined by the machine on which it is runs
    try {
        $runner = ScriptMultiRunner($maxParallelProcesses, "/full/path/to/script");
    } catch (RuntimeException $e) {
        // handle an exception
    }

    for($i = 1; $i <= 1000000; $i++) {
        $changingArg1 = $i - 1;
        $changingArg2 = $i + 1;
        $runner->addProcess((string)$i, $changingArg, $changingArg2);
    }
    $timeout = 15; // Timeout in seconds, depending on the machine it is running on.
    try {
        $results = $runner->runAndWaitForResults($timeout);
    } catch (RuntimeException $e) {
        // handle an exception
    }
    
    foreach ($results as $processId => $processResult) {
        if $processResult->exitCode !== 0 {
            echo "There were errors in " . $processId . ": " . $processResult->stderr;
            continue;
        }
        $result = $processResult->stdout;
        // handle a success result, whatever it is
        
    };

接口的一般描述

根据要执行的对象的类型,可以使用六个不同的类

  1. ProgramMultiRunner 来运行同一程序的多实例;
  2. DiffProgramMultiRunner 来运行不同的程序;
  3. ScriptMultiRunner 来运行同一脚本的多实例;
  4. DiffScriptMultiRunner 来运行不同的脚本(甚至不同的解释器);
  5. CodeMultiRunner 来运行您程序中创建的任何代码;
  6. DiffCodeMultiRunner 来运行您程序中创建的不同代码(可能为不同的解释器)。

所有这些类的构造函数及其 addProcess() 方法的签名当然会有所不同。

在任何情况下,构造函数的第一个参数始终是可启动的并发并行进程的数量。这个数字完全取决于运行包的机器,因此它是第一个参数,并且没有默认值。

明确比隐式好。 --- Python之禅

一个好的起点是512个同时并行进程。

然后有以下三种可能的用法

  1. 运行并获取所有正在运行进程的结果 — runAndWaitForResults()
  2. 运行并忘记(什么都不做) — runAndForget()
  3. 运行并获取前N个结果 — runAndWaitForTheFirstNthResults()

依赖注入期间的依赖反转

如果您需要将某个 MultiRunner 子类作为参数传递给构造函数或其他方法,建议使用 MultiRunnerInterface 接口来消除对特定类的依赖。

    public function someMethodInSomeClass(MultiRunnerInterface $runner) {
        ...
        $processId = 0;
        foreach ($params as $param) {
            $processId++;
            $runner->addProcess((string)$processId, $param);
        }
        $timeToWait = 60;
        
        try {
            $results = $runner->runAndWaitForResults($timeToWait);
        } catch (RuntimeException $e) {
            ...
        }               
        ...
    }

更多示例

多次运行同一程序并使用不同的参数,并获取其工作结果的消息

多次运行同一程序并使用不同的参数,并执行其他操作(运行并忘记)

多次运行同一PHP脚本并使用不同的参数,并获取其输出消息

多次运行同一PHP脚本并使用不同的参数,并仅获取一定数量的关于结果的消息(不需要等待所有正在运行的进程执行)

多次运行同一Python脚本并使用不同的参数,并获取其输出消息

多次运行同一PHP脚本并使用不同的参数,并执行其他操作(运行并忘记)。

使用不同的参数运行不同的脚本,并获取其工作结果的消息

使用不同参数运行不同的脚本,并什么也不做(运行后忘记)

多次使用不同参数运行PHP代码,并获取其输出信息

多次使用不同参数运行PHP代码,并什么也不做(运行后忘记)

使用不同参数运行PHP、Python和node.js代码,并获取其输出信息

使用不同参数运行PHP、Python和node.js代码,并什么也不做(运行后忘记)

安装

您需要

在您的项目中使用

composer require justmisha/php-multirunner

用于开发

在本地项目文件夹中,执行

git clone https://github.com/JustMisha/php-multirunner.git your-folder-for-php-multirunner-code

composer install

测试

从项目文件夹根目录运行所有测试,包括linters和静态分析器

composer test

仅运行单元测试

composer phpunit

由于该包是在Windows上开发的,因此要通过Docker在Linux上运行测试,您可以使用tests\test-linux-all-php.cmd命令文件,该文件将在具有php-cli 7.4、8.0、8.1、8.2、8.3的Docker容器中运行单元测试。或者,您可以使用不同的文件(例如test-linux-php-7.4.cmd)为每个PHP版本运行测试。

测试使用Python和node.js解释器。如果您没有安装它们,则可以使用命令行选项--exclude python,node运行测试,或使用配置文件phpunit.exclude-python-node.xml

贡献

请发送您的建议、评论和pull请求。

对于重大更改,请打开讨论以讨论您的建议。

对于pull请求,请对测试进行适当的更改。

版本控制

我们使用SemVer进行版本控制。

作者

查看参与此项目的贡献者列表

许可

本项目采用MIT许可协议 - 有关详细信息,请参阅LICENSE.md文件。