Skip to content

Commit 78de0c9

Browse files
committed
Merge pull request #31 from async-interop/registry
Add loop bound state registry
2 parents 30fc546 + 3992374 commit 78de0c9

File tree

6 files changed

+154
-1
lines changed

6 files changed

+154
-1
lines changed

composer.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@
66
"require": {
77
"php": ">=5.5.0"
88
},
9+
"require-dev": {
10+
"phpunit/phpunit": "^4|^5"
11+
},
912
"autoload": {
1013
"psr-4": {
1114
"Interop\\Async\\": "src"
1215
}
16+
},
17+
"autoload-dev": {
18+
"psr-4": {
19+
"Interop\\Async\\": "test"
20+
}
1321
}
1422
}

phpunit.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<phpunit bootstrap="./vendor/autoload.php" colors="true">
2+
<testsuites>
3+
<testsuite name="Tests">
4+
<directory>./test</directory>
5+
</testsuite>
6+
</testsuites>
7+
<filter>
8+
<whitelist addUncoveredFilesFromWhitelist="true">
9+
<directory>./src</directory>
10+
</whitelist>
11+
</filter>
12+
</phpunit>

src/Loop.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
final class Loop
66
{
7+
use Registry;
8+
79
/**
810
* @var LoopDriver
911
*/
@@ -20,15 +22,18 @@ final class Loop
2022
public static function execute(callable $callback, LoopDriver $driver)
2123
{
2224
$previousDriver = self::$driver;
25+
$previousRegistry = self::$registry;
2326

2427
self::$driver = $driver;
28+
self::$registry = [];
2529

2630
try {
2731
$callback();
2832

2933
self::$driver->run();
3034
} finally {
3135
self::$driver = $previousDriver;
36+
self::$registry = $previousRegistry;
3237
}
3338
}
3439

src/Registry.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Interop\Async;
4+
5+
trait Registry
6+
{
7+
/**
8+
* @var array
9+
*/
10+
private static $registry = null;
11+
12+
/**
13+
* Stores information in the loop bound registry. This can be used to store
14+
* loop bound information. Stored information is package private.
15+
* Packages MUST NOT retrieve the stored state of other packages.
16+
*
17+
* Therefore packages SHOULD use the following prefix to keys:
18+
* `vendor.package.`
19+
*
20+
* @param string $key namespaced storage key
21+
* @param mixed $value the value to be stored
22+
*
23+
* @return void
24+
*/
25+
public static function storeState($key, $value)
26+
{
27+
if (self::$registry === null) {
28+
throw new \RuntimeException('Not within the scope of an event loop driver');
29+
}
30+
31+
if ($value === null) {
32+
unset(self::$registry[$key]);
33+
} else {
34+
self::$registry[$key] = $value;
35+
}
36+
}
37+
38+
/**
39+
* Fetches information stored bound to the loop. Stored information is
40+
* package private. Packages MUST NOT retrieve the stored state of
41+
* other packages.
42+
*
43+
* Therefore packages SHOULD use the following prefix to keys:
44+
* `vendor.package.`
45+
*
46+
* @param string $key namespaced storage key
47+
*
48+
* @return mixed previously stored value or null if it doesn't exist
49+
*/
50+
public static function fetchState($key)
51+
{
52+
if (self::$registry === null) {
53+
throw new \RuntimeException('Not within the scope of an event loop driver');
54+
}
55+
56+
return isset(self::$registry[$key]) ? self::$registry[$key] : null;
57+
}
58+
}

src/UnsupportedFeatureException.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@
66
* Must be thrown if an optional feature is not supported by the current driver
77
* or system.
88
*/
9-
class UnsupportedFeatureException extends \RuntimeException { }
9+
class UnsupportedFeatureException extends \RuntimeException
10+
{
11+
12+
}

test/RegistryTest.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Interop\Async;
4+
5+
class RegistryTest extends \PHPUnit_Framework_TestCase
6+
{
7+
use Registry;
8+
9+
protected function setUp()
10+
{
11+
self::$registry = null;
12+
}
13+
14+
/**
15+
* @test
16+
* @expectedException \RuntimeException
17+
*/
18+
public function fetchfailsOutsideOfLoop()
19+
{
20+
self::fetchState("foobar");
21+
}
22+
23+
/**
24+
* @test
25+
* @expectedException \RuntimeException
26+
*/
27+
public function storefailsOutsideOfLoop()
28+
{
29+
self::fetchState("store");
30+
}
31+
32+
/** @test */
33+
public function defaultsToNull()
34+
{
35+
// emulate we're in an event loop…
36+
self::$registry = [];
37+
$this->assertNull(self::fetchState("foobar"));
38+
}
39+
40+
/**
41+
* @test
42+
* @dataProvider provideValues
43+
*/
44+
public function fetchesStoredValue($value)
45+
{
46+
// emulate we're in an event loop…
47+
self::$registry = [];
48+
49+
$this->assertNull(self::fetchState("foobar"));
50+
self::storeState("foobar", $value);
51+
52+
$this->assertSame($value, self::fetchState("foobar"));
53+
}
54+
55+
public function provideValues()
56+
{
57+
return [
58+
["string"],
59+
[42],
60+
[1.001],
61+
[true],
62+
[false],
63+
[null],
64+
[new \StdClass],
65+
];
66+
}
67+
}

0 commit comments

Comments
 (0)