Parallel
This is a library for introducing Parallelization into your project.
See the example.php
file for an example how to use this library., (*1)
Theory of Operation
This library will enable the developer to execute a given amount of tasks
(workers) in parallel. This is achieved by adding workers onto a manager,
optionally defining how many processes to run simultaneously and then execute
the manager., (*2)
Under Linux this library will try to detect the number of processors and allow
a maximum number of processes to run equal to the number of processors. If this
cannot be determined or the user is running Windows then a default of 2 is used., (*3)
Requirements and graceful degradation
Parallelization has several requirements. But to allow distribution, without
adding several requirements to your application, will this library execute the
given tasks in serie if the requirements are not met. And throw a E_USER_NOTICE
php error that explains to the user that dependencies are missing., (*4)
The requirements for this library are:, (*5)
- A *NIX compatible operating system
- Scripts must not run from an apache module
- the PCNTL PHP extension (http://php.net/manual/en/book.pcntl.php)
Workers
Workers are basically wrappers around callback functions or methods. As such you
can use anything in your existing project and parallelize it., (*6)
Do note that each parallel process is a duplicate of the original. This means
that, for example, if you pass an object (or other reference) and change that,
that the changes that you have made do not carry over to the caller., (*7)
The return value of the given callback is stored as result on the worker and
can be read using the getResult()
method., (*8)
Any exception that is thrown will result in an error, where the getReturnCode()
method will return the exception code (be warned: this may be 0!) and the
getError()
method will return the exception message., (*9)
Errors and exceptions
if a task throws an exception it is caught and registered as an error. The
exception's code is used as error number, where the message is used as error
message., (*10)
By using this, instead of dying, you can continue execution of the other parallel
processes and handle errors yourself after all processes have been executed., (*11)
Examples
Fluent interface
use MehrAlsNix\Parallel\Manager;
use MehrAlsNix\Parallel\Worker;
$mgr = new Manager();
$mgr
->addWorker(new Worker(function() { sleep(1); return 'a'; }))
->addWorker(new Worker(function() { sleep(1); return 'b'; }))
->addWorker(new Worker(function() { sleep(1); return 'c'; }))
->addWorker(new Worker(function() { sleep(1); return 'd'; }))
->addWorker(new Worker(function() { sleep(1); return 'e'; }))
->execute();
/** @var Worker $worker */
foreach ($mgr as $worker) {
var_dump($worker->getResult());
}
Array interface
use MehrAlsNix\Parallel\Manager;
use MehrAlsNix\Parallel\Worker;
$mgr = new Manager();
$mgr[] = new Worker(function() { sleep(1); return 'f'; });
$mgr[] = new Worker(function() { sleep(1); return 'g'; });
$mgr[] = new Worker(function() { sleep(1); return 'h'; });
$mgr[] = new Worker(function() { sleep(1); return 'i'; });
$mgr[] = new Worker(function() { sleep(1); return 'j'; });
$mgr->execute();
/** @var Worker $worker */
foreach ($mgr as $worker) {
var_dump($worker->getResult());
}
TODO