doujiao2443 2015-06-04 11:55
浏览 73
已采纳

运行与ReactPhp并行的代码

Problem: I need to clone/download several git repositories, unfortunately doing it sequentially takes ages. I got idea to use ReactPhp event loop and do it parallelly.

Despite of many attempts I am not able to get it running parallelly. Maybe I misunderstood the concept, but I expectation was that ReactPhp somehow fork execution of my code.

Could you take a look at my code and share some guidelines how to get it working?

use Symfony\Component\Stopwatch\Stopwatch;

include 'vendor/autoload.php';

$toClone = [
    ['url' => 'http://github.com/symfony/symfony.git', 'dest' => 'C:\tmp\cloneR1'],
    ['url' => 'http://github.com/laravel/laravel.git', 'dest' => 'C:\tmp\cloneR2'],
    ['url' => 'http://github.com/rails/rails.git', 'dest' => 'C:\tmp\cloneR3'],
];
$end = count($toClone);
$i = 0;

$deferred = new React\Promise\Deferred();
$fClone = function (\React\EventLoop\Timer\Timer $timer) use (&$i, $deferred, &$toClone, $end) {
    $project = array_pop($toClone);
    $git = new \GitWrapper\GitWrapper();
    $git->setTimeout(3600);
    $git->cloneRepository($project['url'], $project['dest']);
    $deferred->notify([$i++, $project['url']]);
    if ($end <= $i) {
        $timer->cancel();
        $deferred->resolve();
    }
};

$stopwatch = new Stopwatch();
$stopwatch->start('run');

$loop = React\EventLoop\Factory::create();
$loop->addPeriodicTimer(1, $fClone);

$deferred->promise()->then(function () use ($stopwatch) {
    echo 'DONE' . PHP_EOL;
    $event = $stopwatch->stop('run');
    echo 'Run took ' . $event->getDuration() / 1000 . 'sec and ' . $event->getMemory() . ' bytes of memory';
}, null, function ($data) {
    echo 'RUN ' . $data[0] . ' - ' . $data[1] . PHP_EOL;
});


$loop->run();

my composer.json

{
    "require": {
        "react/promise": "2.2.0",
        "react/event-loop": "0.4.1",
        "cpliakas/git-wrapper": "1.4.1",
        "symfony/stopwatch": "2.7.0"
    }
}

OS: Windows7 PHP: 5.4.8 and 5.5.20
none of these enxtensiosn are installed

"suggest": {
    "ext-libevent": ">=0.1.0",
    "ext-event": "~1.0",
    "ext-libev": "*"
},

so StreamSelectLoop is used

  • 写回答

1条回答 默认 最新

  • dongyingla8668 2015-06-05 15:29
    关注

    The primary issue you're dealing with is that $git->cloneRepository() call is blocking; reactphp just allows for dealing with application level loops. If you don't make your code non-blocking, then your code will still operate in a linear way. You have to suss out how to get the clone to happen in the background; this could be done by forking the process or by calling another php script to run in the background. I am unsure of a git wrapper that operates like this, but if you can find a library that does the git calls in a non-blocking way; then your issue will be mostly resolved.

    ReactPHP doesn't turn php into non-blocking, it just provides the framework to allow for non-blocking techniques. If your code blocks, the react loop will not be run.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置