An simply process manager wrapper API for symfony/process to execute and manage sub-processes.
It's an alternative to pcntl-extension, when not installed. This is part of our symplely/coroutine package for handling any blocking i/o process not handle by Coroutine natively.
The library is to provide an easy to use API to control/manage sub processes for windows OS, and other systems, without any additional software extensions installed.
composer require symplely/processor
include 'vendor/autoload.php';
use Async\Processor\Processor;
// To set the path to PHP executable for child process
Processor::phpPath('/some/path/version-7.3/bin/php');
$process = \spawn($function, $timeout, $channel)
// Or
$process = Processor::create(function () use ($thing) {
// Do a thing
}, $timeout, $channel)
->then(function ($output) {
// Handle success
})->catch(function (\Throwable $exception) {
// Handle exception
});
\spawn_run($process);
// Or
$process->run();
// Second option can be used to set to display child output, default is false
\spawn_run($process, true);
// Or
$process->displayOn()->run();
include 'vendor/autoload.php';
use Async\Processor\Channel;
use Async\Processor\ChannelInterface;
$ipc = new Channel();
$process = spawn(function (ChannelInterface $channel) {
$channel->write('ping'); // same as echo 'ping' or echo fwrite(STDOUT, 'ping')
usleep(1000);
echo $channel->read(); // same as echo fgets(STDIN);
echo $channel->read();
usleep(1000);
return 'return whatever';
}, 300, $ipc)
->progress(function ($type, $data) use ($ipc) {
if ('ping' === $data) {
$ipc->send('pang' . \PHP_EOL);
} elseif (!$ipc->isClosed()) {
$ipc->send('pong' . \PHP_EOL);
->close();
}
});
$ipc->setup($process)
\spawn_run($process);
echo \spawn_output($process); // pingpangpongreturn whatever
// Or
echo $ipc->receive(); // return whatever
When creating asynchronous processes, you'll get an instance of LauncherInterface
returned.
You can add the following event hooks on a process.
$process = spawn($function, $timeout, $channel)
// Or
$process = Processor::create(function () {
// The second argument is optional, Defaults 300.
// it sets The maximum amount of time a process may take to finish in seconds
// The third is optional input pipe to pass to subprocess
}, int $timeout = 300 , $input = null)
->then(function ($output) {
// On success, `$output` is returned by the process.
})
->catch(function ($exception) {
// When an exception is thrown from within a process, it's caught and passed here.
})
->timeout(function () {
// When an time is reached, it's caught and passed here.
})
->progress(function ($type, $data) {
// A IPC like gateway: `$type, $data` is returned by the process progressing, it's producing output.
// This can be use as a IPC handler for real time interaction.
});
There also ->done
, part of ->then()
extended callback method.
->done(function ($result) {
// On success, `$result` is returned by the process or callable you passed to the queue.
});
->then(function ($resultOutput) {
//
}, function ($catchException) {
//
}, function ($progressOutput) {
//
}
);
// To turn on to display child output.
->displayOn();
// Stop displaying child output.
->displayOff();
// To display child output, only by third party means once turned on.
->display();
// Processes can be retried.
->restart();
->run();
If an Exception
or Error
is thrown from within a child process, it can be caught per process by specifying a callback in the ->catch()
method.
If there's no error handler added, the error will be thrown in the parent process when calling spawn_run()
or $process->run()
.
If the child process would unexpectedly stop without throwing an Throwable
, the output written to stderr
will be wrapped and thrown as Async\Processor\ProcessorError
in the parent process.
Contributions are encouraged and welcome; I am always happy to get feedback or pull requests on Github :) Create Github Issues for bugs and new features and comment on the ones you are interested in.
The MIT License (MIT). Please see License File for more information.