Skip to content

Commit 13c93af

Browse files
committed
Merge pull request #30 from async-interop/factory
Add LoopDriverFactory
2 parents 662cfdc + 1c1e740 commit 13c93af

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

src/Loop.php

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,36 @@ final class Loop
66
{
77
use Registry;
88

9+
/**
10+
* @var LoopDriverFactory
11+
*/
12+
private static $factory = null;
13+
914
/**
1015
* @var LoopDriver
1116
*/
1217
private static $driver = null;
1318

19+
/**
20+
* @var bool
21+
*/
22+
private static $running = false;
23+
24+
/**
25+
* Set the factory to be used to create a driver if none is passed to
26+
* self::execute. A default driver will be created if none is running
27+
* to support synchronous waits in traditional applications.
28+
*/
29+
public static function setFactory(LoopDriverFactory $factory = null)
30+
{
31+
self::$factory = $factory;
32+
33+
if (!self::$running) {
34+
self::$driver = self::createDriver();
35+
self::$registry = [];
36+
}
37+
}
38+
1439
/**
1540
* Execute a callback within the scope of an event loop driver.
1641
*
@@ -19,13 +44,16 @@ final class Loop
1944
*
2045
* @return void
2146
*/
22-
public static function execute(callable $callback, LoopDriver $driver)
47+
public static function execute(callable $callback, LoopDriver $driver = null)
2348
{
24-
$previousDriver = self::$driver;
2549
$previousRegistry = self::$registry;
50+
$previousDriver = self::$driver;
51+
52+
$driver = $driver ?: self::createDriver();
2653

2754
self::$driver = $driver;
2855
self::$registry = [];
56+
self::$running = true;
2957

3058
try {
3159
$callback();
@@ -34,9 +62,31 @@ public static function execute(callable $callback, LoopDriver $driver)
3462
} finally {
3563
self::$driver = $previousDriver;
3664
self::$registry = $previousRegistry;
65+
self::$running = false;
3766
}
3867
}
3968

69+
/**
70+
* Create a new driver if a factory is present, otherwise throw.
71+
*
72+
* @throws \LogicException if no factory is set or no driver returned from factory
73+
*/
74+
private static function createDriver()
75+
{
76+
if (self::$factory === null) {
77+
throw new \LogicException("No loop driver factory set; Either pass a driver to Loop::execute or set a factory.");
78+
}
79+
80+
$driver = self::$factory->create();
81+
82+
if (!$driver instanceof LoopDriver) {
83+
$type = is_object($driver) ? "an instance of " . get_class($driver) : gettype($driver);
84+
throw new \LogicException("Loop driver factory returned {$type}, but must return an instance of LoopDriver.");
85+
}
86+
87+
return $driver;
88+
}
89+
4090
/**
4191
* Retrieve the event loop driver that is in scope.
4292
*
@@ -45,7 +95,7 @@ public static function execute(callable $callback, LoopDriver $driver)
4595
public static function get()
4696
{
4797
if (null === self::$driver) {
48-
throw new \RuntimeException('Not within the scope of an event loop driver');
98+
throw new \RuntimeException('Missing driver; Neither in Loop::execute nor factory set.');
4999
}
50100

51101
return self::$driver;
@@ -232,12 +282,16 @@ public static function setErrorHandler(callable $callback = null)
232282
*
233283
* @return bool
234284
*/
235-
public static function supports($feature) {
285+
public static function supports($feature)
286+
{
236287
return self::get()->supports($feature);
237288
}
238289

239290
/**
240291
* Disable construction as this is a static class.
241292
*/
242-
private function __construct() {}
293+
private function __construct()
294+
{
295+
// intentionally left blank
296+
}
243297
}

src/LoopDriverFactory.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Interop\Async;
4+
5+
interface LoopDriverFactory
6+
{
7+
/**
8+
* Create a new event loop driver instance.
9+
*
10+
* @return LoopDriver
11+
*/
12+
public function create();
13+
}

0 commit comments

Comments
 (0)