kmuenkel/parallel-collection

AmpPHP的Laravel包装器,提供执行并行处理的集合宏

v1.0.11 0202-03-07 15:00 UTC

This package is auto-updated.

Last update: 2024-09-24 04:44:08 UTC


README

AmpPHP的Laravel包装器,提供执行并行处理的集合宏。

有一个类似的包叫做spatie/laravel-collection-macros,也尝试这样做,但当并行闭包试图利用Laravel抽象或模型实例时,就不够好了。问题是,类似于隔离的PhpUnit测试,当闭包被初始化以执行时,App需要重新初始化。此外,序列化和反序列化模型类并不是一个简单的过程,因为需要重新建立数据库连接。然而,Laravel已经解决了这个问题,即在序列化闭包用于队列作业的上下文中。所以这两个问题都可以使用框架中现有的特性来解决。

请注意,虽然AmPhp提供真正的并行处理,但父线程仍然需要在所有子线程解决之前等待,以便关闭。类似于分叉,这似乎是PHP本身的限制,如果子任务被允许在父任务关闭之后解决,那么父任务可能会尝试提前终止子任务,或者子线程在执行完成后不会被指令释放其资源,从而导致僵尸进程。如果目的是触发一个稍后解决的进程,而不会使父任务等待,你仍然需要使用类似队列作业的东西。然而,队列和此并行处理器的组合可以兼得两者之优,并且性能极好。

用法

并行闭包

如果并行处理的项本身是闭包,不需要特殊处理。

$process1 = function () {
    sleep(5);   //Simulate taking a long time to handle the item
    return 'perform some long process';
};

$process2 = function () {
    sleep(5);   //Simulate taking a long time to handle the item
    return 'perform another long process';
};

$items = compact('process1', 'process1');

$before = now();
$results = collect($items)->mapToParallel()->toArray();
$after = now();

$elapsedTime = $after->diffInSeconds($before);
print_r(compact('results', 'elapsedTime'));

/**
 * Array:
 * (
 *    "results" => Array
 *    (
 *       ["process1"] => 'perform some long process'
 *       ["process2"] => 'perform another long process'
 *    )
 *    "elapsedTime" => 5
 * )
 */

带有处理器的并行项

如果你的项不是闭包,而是需要处理,示例将如下所示

$items = ['Hello', 'World'];
$handler = function (string $item) {
    sleep(5);   //Simulate taking a long time to handle the item

    return $item;
};

$before = now();
$results = collect($items)->mapToParallel($handler)->toArray();
$after = now();

$elapsedTime = $after->diffInSeconds($before);
print_r(compact('results', 'elapsedTime'));

/**
 * Array:
 * (
 *    "results" => Array
 *    (
 *       [0] => 'Hello'
 *       [1] => 'World'
 *    )
 *    "elapsedTime" => 5
 * )
 */