1
0
mirror of https://github.com/danog/amp.git synced 2024-12-12 17:37:34 +01:00

Merge pull request #30 from async-interop/factory

Add LoopDriverFactory
This commit is contained in:
Bob Weinand 2016-05-20 12:59:21 +02:00
commit 13c93afca4
2 changed files with 72 additions and 5 deletions

View File

@ -6,11 +6,36 @@ final class Loop
{ {
use Registry; use Registry;
/**
* @var LoopDriverFactory
*/
private static $factory = null;
/** /**
* @var LoopDriver * @var LoopDriver
*/ */
private static $driver = null; private static $driver = null;
/**
* @var bool
*/
private static $running = false;
/**
* Set the factory to be used to create a driver if none is passed to
* self::execute. A default driver will be created if none is running
* to support synchronous waits in traditional applications.
*/
public static function setFactory(LoopDriverFactory $factory = null)
{
self::$factory = $factory;
if (!self::$running) {
self::$driver = self::createDriver();
self::$registry = [];
}
}
/** /**
* Execute a callback within the scope of an event loop driver. * Execute a callback within the scope of an event loop driver.
* *
@ -19,13 +44,16 @@ final class Loop
* *
* @return void * @return void
*/ */
public static function execute(callable $callback, LoopDriver $driver) public static function execute(callable $callback, LoopDriver $driver = null)
{ {
$previousDriver = self::$driver;
$previousRegistry = self::$registry; $previousRegistry = self::$registry;
$previousDriver = self::$driver;
$driver = $driver ?: self::createDriver();
self::$driver = $driver; self::$driver = $driver;
self::$registry = []; self::$registry = [];
self::$running = true;
try { try {
$callback(); $callback();
@ -34,9 +62,31 @@ final class Loop
} finally { } finally {
self::$driver = $previousDriver; self::$driver = $previousDriver;
self::$registry = $previousRegistry; self::$registry = $previousRegistry;
self::$running = false;
} }
} }
/**
* Create a new driver if a factory is present, otherwise throw.
*
* @throws \LogicException if no factory is set or no driver returned from factory
*/
private static function createDriver()
{
if (self::$factory === null) {
throw new \LogicException("No loop driver factory set; Either pass a driver to Loop::execute or set a factory.");
}
$driver = self::$factory->create();
if (!$driver instanceof LoopDriver) {
$type = is_object($driver) ? "an instance of " . get_class($driver) : gettype($driver);
throw new \LogicException("Loop driver factory returned {$type}, but must return an instance of LoopDriver.");
}
return $driver;
}
/** /**
* Retrieve the event loop driver that is in scope. * Retrieve the event loop driver that is in scope.
* *
@ -45,7 +95,7 @@ final class Loop
public static function get() public static function get()
{ {
if (null === self::$driver) { if (null === self::$driver) {
throw new \RuntimeException('Not within the scope of an event loop driver'); throw new \RuntimeException('Missing driver; Neither in Loop::execute nor factory set.');
} }
return self::$driver; return self::$driver;
@ -232,12 +282,16 @@ final class Loop
* *
* @return bool * @return bool
*/ */
public static function supports($feature) { public static function supports($feature)
{
return self::get()->supports($feature); return self::get()->supports($feature);
} }
/** /**
* Disable construction as this is a static class. * Disable construction as this is a static class.
*/ */
private function __construct() {} private function __construct()
{
// intentionally left blank
}
} }

13
src/LoopDriverFactory.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace Interop\Async;
interface LoopDriverFactory
{
/**
* Create a new event loop driver instance.
*
* @return LoopDriver
*/
public function create();
}