Skip to content

Instantly share code, notes, and snippets.

@stefanotorresi
Created July 21, 2017 21:22
Show Gist options
  • Save stefanotorresi/eabce06cf264913797a12faab1dc7c65 to your computer and use it in GitHub Desktop.
Save stefanotorresi/eabce06cf264913797a12faab1dc7c65 to your computer and use it in GitHub Desktop.
Run multiple processes concurrently with amphp/process and coroutines
<?php
declare(strict_types=1);
use Amp\ByteStream\Message;
use Amp\Loop;
use Amp\Process\Process;
use function Amp\coroutine;
use function Amp\Promise\all;
require 'vendor/autoload.php';
define('STOP_ON_ERROR', false);
Loop::run(function() {
$totalStart = microtime(true);
$processes = [
'foobar' => new Process("sleep 3 && echo this is foobar"),
'barbaz' => new Process("sleep 2 && echo this is barbaz"),
'batman' => new Process("sleep 1 && echo this is batman && exit 1")
];
$runProcess = coroutine(function(Process $process, string $name): iterable {
$start = microtime(true);
$process->start();
$exitCode = yield $process->join();
$elapsed = number_format(microtime(true) - $start, 3);
$stdout = trim(yield new Message($process->getStdout()));
if ($exitCode > 0 && STOP_ON_ERROR) {
throw new Exception("Process $name exited after {$elapsed}s with code $exitCode and this output: \n$stdout");
}
return compact('name', 'exitCode', 'stdout', 'elapsed');
});
// magic happens: mappa una coroutine per processo, e le attende tutte concorrenzialmente
$outputs = yield all(array_map($runProcess, $processes, array_keys($processes)));
var_dump($outputs);
$totalElapsed = microtime(true) - $totalStart;
echo PHP_EOL , "Total elapsed time: $totalElapsed" , PHP_EOL;
});
{
"require": {
"php": "^7.1",
"amphp/process": "^0.2.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment