Skip to content

Commit

Permalink
Added functions, reactor globals
Browse files Browse the repository at this point in the history
  • Loading branch information
rdlowrey committed Aug 1, 2014
1 parent 16190c9 commit 6777532
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.idea
composer.lock
vendor
test/coverage
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

- none

v0.10.0
-------

- Added *functions.php* API for reactor use in procedural and functional code.
- `ReactoryFactory::select()` is now a static singleton method. Single-threaded code should never
use multiple event loops. This change is made to ease `Reactor` procurement and minimize bugs
from the existence of multiple `Reactor` instances in the same thread. It is *NOT*, however, an
excuse to forego dependency injection. Do not abuse the global nature of the event loop. Lazy
injection is fine, but laziness on your part as a programmer is not.

> **BC BREAKS:**
- The `ReactorFactory::__invoke()` magic method has been removed. Any code relying on it must migrate
references to `ReactoryFactory::select()`

v0.9.0
------

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
}
},
"branch-alias": {
"dev-master": "0.9.x-dev"
"dev-master": "0.10.x-dev"
},
"repositories": [
{
Expand Down
36 changes: 26 additions & 10 deletions lib/ReactorFactory.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,36 @@

namespace Alert;

/**
* The event reactor is a truly global thing in single-threaded code. Applications should use
* a single reactor per thread. Accidentally using multiple reactors can lead to all manner of
* hard-to-debug problems. Should you almost always avoid static and singletons? Yes, and if you
* abuse this static factory method it's your fault. However, there is nothing wrong with
* asking for a Reactor instance in your code and using lazy injection via this method if it's
* not provided.
*
* DO NOT instantiate multiple event loops in your PHP application!
*/
class ReactorFactory {
public function __invoke() {
return $this->select();
}
private static $reactor;

public function select() {
if (extension_loaded('uv')) {
$reactor = new UvReactor;
/**
* Select a global event reactor based on the current environment
*
* @param callable $factory An optional factory callable to generate the shared reactor yourself
* @return Alert\Reactor
*/
public static function select(callable $factory = null) {
if (self::$reactor) {
return self::$reactor;
} elseif ($factory) {
return $self::reactor = $factory();
} elseif (extension_loaded('uv')) {
return $self::reactor = new UvReactor;
} elseif (extension_loaded('libevent')) {
$reactor = new LibeventReactor;
return $self::reactor = new LibeventReactor;
} else {
$reactor = new NativeReactor;
return $self::reactor = new NativeReactor;
}

return $reactor;
}
}
59 changes: 59 additions & 0 deletions lib/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Alert;

function immediately(callable $func) {
return ReactorFactory::select()->immediately($func);
}

function once(callable $func, $msDelay) {
return ReactorFactory::select()->once($func, $msDelay);
}

function repeat(callable $func, $msDelay) {
return ReactorFactory::select()->repeat($func, $msDelay);
}

function at(callable $func, $timeString) {
return ReactorFactory::select()->at($func, $timeString);
}

function enable($watcherId) {
ReactorFactory::select()->enable($watcherId);
}

function disable($watcherId) {
ReactorFactory::select()->disable($watcherId);
}

function cancel($watcherId) {
ReactorFactory::select()->cancel($watcherId);
}

function onReadable($stream, callable $function, $enableNow = true) {
return ReactorFactory::select()->onReadable($stream, $function, $enableNow);
}

function onWritable($stream, callable $function, $enableNow = true) {
return ReactorFactory::select()->onWritable($stream, $function, $enableNow);
}

function watchStream($stream, $flags, callable $func) {
return ReactorFactory::select()->watchStream($stream, $flags, $func);
}

function tick() {
ReactorFactory::select()->tick();
}

function run(callable $onStart = null) {
ReactorFactory::select()->run($onStart);
}

function stop() {
ReactorFactory::select()->stop();
}

function reactor() {
return ReactorFactory::select();
}

0 comments on commit 6777532

Please sign in to comment.