1
0
mirror of https://github.com/danog/parallel.git synced 2024-12-02 09:37:57 +01:00

Add ContextFactory

This commit is contained in:
Aaron Piotrowski 2020-02-14 17:22:41 -06:00
parent 53a97cbd92
commit d706f1db2f
No known key found for this signature in database
GPG Key ID: ADD1EF783EDE9EEB
4 changed files with 125 additions and 12 deletions

View File

@ -0,0 +1,28 @@
<?php
namespace Amp\Parallel\Context;
use Amp\Promise;
interface ContextFactory
{
/**
* Creates a new execution context.
*
* @param string|string[] $script Path to PHP script or array with first element as path and following elements options
* to the PHP script (e.g.: ['bin/worker', 'Option1Value', 'Option2Value'].
*
* @return Context
*/
public function create($script): Context;
/**
* Creates and starts a new execution context.
*
* @param string|string[] $script Path to PHP script or array with first element as path and following elements options
* to the PHP script (e.g.: ['bin/worker', 'Option1Value', 'Option2Value'].
*
* @return Promise<Context>
*/
public function run($script): Promise;
}

View File

@ -0,0 +1,36 @@
<?php
namespace Amp\Parallel\Context;
use Amp\Promise;
class DefaultContextFactory implements ContextFactory
{
function create($script): Context
{
/**
* Creates a thread if ext-parallel is installed, otherwise creates a child process.
*
* @inheritdoc
*/
if (Parallel::isSupported()) {
return new Parallel($script);
}
return new Process($script);
}
/**
* Creates and starts a thread if ext-parallel is installed, otherwise creates a child process.
*
* @inheritdoc
*/
function run($script): Promise
{
if (Parallel::isSupported()) {
return Parallel::run($script);
}
return Process::run($script);
}
}

View File

@ -2,32 +2,53 @@
namespace Amp\Parallel\Context;
use Amp\Loop;
use Amp\Promise;
const LOOP_FACTORY_IDENTIFIER = ContextFactory::class;
/**
* @param string|string[] $script
* @param string|string[] $script Path to PHP script or array with first element as path and following elements options
* to the PHP script (e.g.: ['bin/worker', 'Option1Value', 'Option2Value'].
*
* @return Context
*/
function create($script): Context
{
if (Parallel::isSupported()) {
return new Parallel($script);
}
return new Process($script);
return factory()->create($script);
}
/**
* @param string|string[] $script
* Creates and starts a process based on installed extensions (a thread if ext-parallel is installed, otherwise a child
* process).
*
* @param string|string[] $script Path to PHP script or array with first element as path and following elements options
* to the PHP script (e.g.: ['bin/worker', 'Option1Value', 'Option2Value'].
*
* @return Promise<Context>
*/
function run($script): Promise
{
if (Parallel::isSupported()) {
return Parallel::run($script);
}
return Process::run($script);
return factory()->run($script);
}
/**
* Gets or sets the global context factory.
*
* @param ContextFactory|null $factory
*
* @return ContextFactory
*/
function factory(?ContextFactory $factory = null): ContextFactory
{
if ($factory === null) {
$factory = Loop::getState(LOOP_FACTORY_IDENTIFIER);
if ($factory) {
return $factory;
}
$factory = new DefaultContextFactory;
}
Loop::setState(LOOP_FACTORY_IDENTIFIER, $factory);
return $factory;
}

View File

@ -0,0 +1,28 @@
<?php
namespace Amp\Parallel\Test\Context;
use Amp\Parallel\Context\Context;
use Amp\Parallel\Context\DefaultContextFactory;
use Amp\Parallel\Sync\ContextPanicError;
use Amp\PHPUnit\AsyncTestCase;
class DefaultWorkerFactoryTest extends AsyncTestCase
{
public function testCreate(): void
{
$factory = new DefaultContextFactory;
$context = $factory->create(__DIR__ . '/Fixtures/test-process.php');
$this->assertInstanceOf(Context::class, $context);
}
public function testRun(): \Generator
{
$this->expectException(ContextPanicError::class);
$this->expectExceptionMessage('No string provided');
$factory = new DefaultContextFactory;
$context = yield $factory->run(__DIR__ . '/Fixtures/test-process.php');
yield $context->join();
}
}