Skip to content

Commit

Permalink
Reverted to use the react loop
Browse files Browse the repository at this point in the history
Bootstrap Rx scheduler
  • Loading branch information
davidwdan committed Mar 14, 2017
1 parent 024f293 commit 4cd6bc2
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 22 deletions.
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
}
],
"require": {
"wyrihaximus/react-async-interop-loop": "^0.2.1"
"react/event-loop": "^0.4.2"
},
"autoload": {
"psr-4": {
"EventLoop\\": "src"
},
"files": [
"src/functions.php",
"src/bootstrap.php"
]
}
Expand Down
51 changes: 51 additions & 0 deletions src/EventLoop.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace EventLoop;

use React\EventLoop\Factory;
use React\EventLoop\LibEventLoop;
use React\EventLoop\LoopInterface;

class EventLoop
{
/** @var LibEventLoop */
static private $loop;

static public function setLoop(LoopInterface $loop) {
if (static::$loop === null) {
static::$loop = $loop;
}

if (static::$loop !== $loop) {
throw new \Exception("Two different loop instances created. Something is not right.");
}

static::registerLoopRunner();
}

static public function getLoop() {
if (static::$loop) {
return static::$loop;
}

static::$loop = Factory::create();

static::registerLoopRunner();

return static::$loop;
}

static private function registerLoopRunner() {
$hasBeenRun = false;

register_shutdown_function(function () use (&$hasBeenRun) {
if (!$hasBeenRun) {
EventLoop::getLoop()->run();
}
});

static::$loop->nextTick(function () use (&$hasBeenRun) {
$hasBeenRun = true;
});
}
}
13 changes: 5 additions & 8 deletions src/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
<?php

use Interop\Async\Loop;
use WyriHaximus\React\AsyncInteropLoop\ReactDriverFactory;

Loop::setFactory(ReactDriverFactory::createFactory());

register_shutdown_function(function () {
Loop::execute(function () {}, Loop::get());
});
if (class_exists('\Rx\Scheduler\EventLoopScheduler') && class_exists('\Rx\Scheduler')) {
\Rx\Scheduler::setDefaultFactory(function () {
return new \Rx\Scheduler\EventLoopScheduler(\EventLoop\getLoop());
});
}
71 changes: 71 additions & 0 deletions src/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace EventLoop;

use React\EventLoop\LoopInterface;
use React\EventLoop\Timer\TimerInterface;

/**
* @param LoopInterface $loop
* @throws \Exception
*/
function setLoop(LoopInterface $loop) {
EventLoop::setLoop($loop);
}

/**
* @return \React\EventLoop\LibEventLoop
*/
function getLoop() {
return EventLoop::getLoop();
}

/**
* Enqueue a callback to be invoked once after the given interval.
*
* The execution order of timers scheduled to execute at the same time is
* not guaranteed.
*
* @param int|float $interval The number of seconds to wait before execution.
* @param callable $callback The callback to invoke.
*
* @return TimerInterface
*/
function addTimer($interval, callable $callback) {
return getLoop()->addTimer($interval, $callback);
}

/**
* Enqueue a callback to be invoked repeatedly after the given interval.
*
* The execution order of timers scheduled to execute at the same time is
* not guaranteed.
*
* @param int|float $interval The number of seconds to wait before execution.
* @param callable $callback The callback to invoke.
*
* @return TimerInterface
*/
function addPeriodicTimer($interval, callable $callback) {
return getLoop()->addPeriodicTimer($interval, $callback);
}

/**
* Cancel a pending timer.
*
* @param TimerInterface $timer The timer to cancel.
*/
function cancelTimer(TimerInterface $timer) {
getLoop()->cancelTimer($timer);
}

/**
* Check if a given timer is active.
*
* @param TimerInterface $timer The timer to check.
*
* @return boolean True if the timer is still enqueued for execution.
*/
function isTimerActive(TimerInterface $timer) {
return getLoop()->isTimerActive($timer);
}
57 changes: 44 additions & 13 deletions tests/Unit/EventLoopTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,58 @@

namespace EventLoop\Tests\Unit;

use EventLoop\EventLoop;
use EventLoop\Tests\TestCase;
use Interop\Async\Loop;
use React\EventLoop\Factory;

class EventLoopTest extends TestCase
{
public function testAutoStart()
private function resetStaticLoop() {
$ref = new \ReflectionClass(EventLoop::class);
$prop = $ref->getProperty('loop');
$prop->setAccessible(true);
$prop->setValue(null);
$prop->setAccessible(false);
}

public function setup() {
$this->resetStaticLoop();
}

public function testSetLoop()
{
Loop::defer(function () {
$this->assertTrue(true);
});
$loop = Factory::create();

\EventLoop\setLoop($loop);

$this->assertSame($loop, \EventLoop\getLoop());
}

public function testDefer()
public function testSetLoopSameInstance()
{
$started = false;
Loop::defer(function () use (&$started) {
$started = true;
});
$loop = \EventLoop\getLoop();

\EventLoop\setLoop($loop);

Loop::get()->run();
$this->assertSame($loop, \EventLoop\getLoop());
}

public function testGetLoopWithoutSet() {
$loop = \EventLoop\getLoop();

$this->assertSame($loop, \EventLoop\getLoop());
}

/**
* @expectedException \Exception
*/
public function testSettingDifferentInstance() {
\EventLoop\getLoop();

\EventLoop\setLoop(Factory::create());
}

$this->assertTrue($started);
public function testGetLoopTwice() {
$this->assertSame(\EventLoop\getLoop(), \EventLoop\getLoop());
}
}
}

0 comments on commit 4cd6bc2

Please sign in to comment.