console-helpers/process-iterator

并行运行 Symfony 进程的顺序方式

v1.0.0 2016-03-05 22:12 UTC

This package is auto-updated.

Last update: 2024-09-09 00:28:20 UTC


README

CI codecov Scrutinizer Code Quality

Latest Stable Version Total Downloads License

ProcessIterator 是一个 PHP 类,允许编写顺序代码来处理并行运行的进程。

这是 Phabricator 项目中 FutureIterator 类的修改版,该版本与 Symfony Process 组件兼容。

安装

  • 执行以下命令以添加依赖项:php composer.phar require console-helpers/process-iterator:dev-master

使用

重要:键被保留,但元素顺序不保证。迭代按照执行顺序进行,所以最快的进程将首先得到。这允许您尽可能早地进行后续处理。

<?php

use ConsoleHelpers\ProcessIterator\ProcessIterator;
use Symfony\Component\Process\Process;

$processes = array(
	'a.txt' => new Process('wc -c a.txt'),
	'b.txt' => new Process('wc -c b.txt'),
	'c.txt' => new Process('wc -c c.txt'),
);


// All of the processes will be started at once, when "foreach" line is executed.
$process_iterator = new ProcessIterator($processes);

foreach ($process_iterator as $key => $process) {
	$stderr = $process->getErrorOutput();
	$stdout = $process->getOutput();
	do_some_processing($stdout);
}


// Will only run 2 processes in parallel at a time.
$process_iterator = new ProcessIterator($processes);
$process_iterator->limit(2);

foreach ($process_iterator as $key => $process) {
	$stderr = $process->getErrorOutput();
	$stdout = $process->getOutput();
	do_some_processing($stdout);
}


// Will run all processes in parallel. The $processes array can be inspected later 
// to see execution results.
$process_iterator = new ProcessIterator($processes);
$process_iterator->runAll();


// Allows to add more processes in real time as they are processed.
$process_iterator = new ProcessIterator($processes);

foreach ($process_iterator as $key => $process) {
	$stderr = $process->getErrorOutput();
	$stdout = $process->getOutput();
	do_some_processing($stdout);

	if ( $key === 'b.txt' ) {
		$process_iterator->addProcess(
			new Process('wc -c d.txt'),
			'd.txt'
		);
	}
}


// Show "processing ..." message at if no process was finished executing after 
// given time has passed. This can happen several times as well.
$process_iterator = new ProcessIterator($processes);
$process_iterator->setUpdateInterval(1);

foreach ($process_iterator as $key => $process) {
	if ($process === null) {
		echo "Still working...\n";
	}
	else {
		$stderr = $process->getErrorOutput();
		$stdout = $process->getOutput();
		do_some_processing($stdout);
	}
}


// Safe process exception detection. When exception happens during process 
// execution it's recorded and that process is immediately yielded. Then
// the $process_iterator->getProcessException() method can be used to 
// handle it gracefully (e.g. re-add back to queue).
$process_iterator = new ProcessIterator($processes);

foreach ($process_iterator as $key => $process) {
	$process_exception = $process_iterator->getException();

	if ( $process_exception instanceof ProcessTimedOutException ) {
		echo "The $key process timed out.\n";
	}
	elseif ( $process_exception instanceof ProcessFailedException ) {
		echo "The $key process has failed.\n";
	}
	else {
		$stderr = $process->getErrorOutput();
		$stdout = $process->getOutput();
		do_some_processing($stdout);
	}
}

贡献

查看 CONTRIBUTING 文件。

许可

ProcessIterator 在 BSD-3-Clause 许可下发布。有关详细信息,请参阅附带LICENSE 文件。