乐趣区

关于php:PHP-多进程任务-spatieasync-扩展使用说明

spatie/async 是为 PHP 基于 PCNTL 扩大开发的,可能应用多过程解决工作。

我的项目地址

spatie/async

惯例应用示例

对象模式

use Spatie\Async\Pool;

$pool = Pool::create()
// 抉择执行 PHP
->withBinary('/path/to/php')
// 可同时运行的最大过程数
->concurrency(20)
// 过程实现所需的最长工夫 (以秒为单位),反对小数点地位以实现更细粒度的超时
->timeout(15)
// 配置应该应用哪个主动加载器子流程
->autoload(__DIR__ . '/../../vendor/autoload.php')
// 配置循环应该休眠多长时间,而后从新查看过程状态 (以微秒为单位)。->sleepTime(50000);

foreach ($things as $thing) {$pool->add(function () use ($thing) {// 增加工作})->then(function ($output) {
        // 工作执行结束回调函数,返回后果会以变量 $output 注入回调函数

        // $pool->stop(); 提前终止 pool 工作池执行,终止后想要持续应用则须要从新创立工作池})->catch(function (MyException $e) {// 捕获异样})
    ->catch(function (Exception $e) {// / 捕获异样,反对不做多个})->timeout(function () {// 超时解决});
}
$pool->wait();

函数应用形式

use Spatie\Async\Pool;

$pool = Pool::create();

foreach (range(1, 5) as $i) {$pool[] = async(function () {usleep(random_int(10, 1000));
        return 2;
    })->then(function (int $output) {echo $output.PHP_EOL;});
}

await($pool);

工作类应用形式

须要创立工作类,并继承类 Spatie\Async\Task,工作执行会调用 task 工作类的 run() 办法

use Spatie\Async\Task;

class MyTask extends Task
{public function configure()
    {// 加载配置,如:依赖容器、外围类加载}

    public function run()
    {// 工作工作程序}
}

// Add the task to the pool
$pool = Pool::create();
$pool->add(new MyTask());
$pool->wait();

补充:在 Laravel 中应用留神

如果没有加载 bootstrap/app.php 配置,则无奈应用 Laravel 提供的类办法。比方:应用 Illuminate\Support\Facades\Log 时会报异样 Exception: A facade root has not been set

未加载 bootstrap/app.php 示例

<?php
namespace App\Task;

use Spatie\Async\Task;
use Illuminate\Support\Facades\Log;

class EmployTask extends Task
{public function configure()
    { }

    public function run()
    {$datetime = date('Y-m-d H:i:s');
        Log::error('EmployTask',['type' => 'use Log','msg' => '未加载 bootstrap/app.php', 'datetime' => $datetime]);
    }
}

报错信息如下

[2022-03-28 17:26:17] local.ERROR: EmployTask {"msg":"A facade root has not been set.

#0 /www/wwwroot/laravel/app/Task/EmployTask.php(23): Illuminate\\Support\\Facades\\Facade::__callStatic()
#1 /www/wwwroot/laravel/app/Task/EmployTask.php(17): App\\Task\\EmployTask->test()
#2 /www/wwwroot/laravel/vendor/spatie/async/src/Task.php(15): App\\Task\\EmployTask->run()
#3 /www/wwwroot/laravel/vendor/spatie/async/src/Runtime/ChildRuntime.php(26): Spatie\\Async\\Task->__invoke()
#4 {main}"} 

加载 bootstrap/app.php 示例

<?php
namespace App\Task;

use Spatie\Async\Task;
use Illuminate\Support\Facades\Log;

class EmployTask extends Task
{public function configure()
    {
        $app = require __DIR__.'/../../bootstrap/app.php';
        $kernel = $app->make(\Illuminate\Contracts\Console\Kernel::class);
        $kernel->bootstrap();}

    public function run()
    {$datetime = date('Y-m-d H:i:s');
        Log::error('EmployTask',['type' => 'use Log','msg' => '加载 bootstrap/app.php', 'datetime' => $datetime]);
    }
}


// 也能够这样应用

$pool[] = async(function () use ($result, $syncemployRepository) {
    $app = require __DIR__.'/../../../../bootstrap/app.php';
    $kernel = $app->make(\Illuminate\Contracts\Console\Kernel::class);
    $kernel->bootstrap();
    // 工作代码
})->then(function ($output) use($pool) {$pool->stop();
})->catch(function (Exception $e) {Log::error('createauth_sync', ['msg' => $e->getMessage()]);
});

记录日志如下

[2022-03-28 17:28:26] local.ERROR: EmployTask {"type":"use Log","msg":"加载 bootstrap/app.php","datetime":"2022-03-28 17:28:26"} 

起因阐明

作者在文档中有阐明 Besides using closures, you can also work with a Task. A Task is useful in situations where you need more setup work in the child process. Because a child process is always bootstrapped from nothing, chances are you'll want to initialise eg. the dependency container before executing the task. The Task class makes this easier to do.(除了能够应用闭包,还能够应用 Task 工作。使用者有可能须要在子过程中加载更多设置。子过程总是从零开始启动的,所以就须要进行初始化。比方:加载依赖容器、外围类)

退出移动版