From c52f792721bf70c0fb645293d8b991695399b5a1 Mon Sep 17 00:00:00 2001 From: Jan Sorgalla Date: Sat, 11 Mar 2017 10:54:55 +0100 Subject: [PATCH 1/2] Introduce a global loop --- src/GlobalLoop.php | 78 ++++++++++++++++++++++++++++++++++++++++ tests/GlobalLoopTest.php | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 src/GlobalLoop.php create mode 100644 tests/GlobalLoopTest.php diff --git a/src/GlobalLoop.php b/src/GlobalLoop.php new file mode 100644 index 00000000..f95b4f62 --- /dev/null +++ b/src/GlobalLoop.php @@ -0,0 +1,78 @@ +futureTick(function () { + self::$didRun = true; + }); + + return self::$loop; + } + + public static function reset() + { + self::$loop = null; + self::$didRun = false; + } + + /** + * @return LoopInterface + */ + public static function create() + { + if (self::$factory) { + return self::createFromCustomFactory(self::$factory); + } + + return Factory::create(); + } + + private static function createFromCustomFactory(callable $factory) + { + $loop = call_user_func($factory); + + if (!$loop instanceof LoopInterface) { + throw new \LogicException( + sprintf( + 'The GlobalLoop factory must return an instance of LoopInterface but returned %s.', + is_object($loop) ? get_class($loop) : gettype($loop) + ) + ); + } + + return $loop; + } +} diff --git a/tests/GlobalLoopTest.php b/tests/GlobalLoopTest.php new file mode 100644 index 00000000..4ec94729 --- /dev/null +++ b/tests/GlobalLoopTest.php @@ -0,0 +1,76 @@ +assertInstanceOf('React\EventLoop\LoopInterface', GlobalLoop::get()); + } + + public function testSubsequentGetCallsReturnSameInstance() + { + $this->assertSame(GlobalLoop::get(), GlobalLoop::get()); + } + + public function testSubsequentGetCallsReturnNotSameInstanceWhenResetting() + { + $loop = GlobalLoop::get(); + + GlobalLoop::reset(); + + $this->assertNotSame($loop, GlobalLoop::get()); + } + + public function testCreatesLoopWithFactory() + { + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface') + ->getMock(); + + $factory = $this->createCallableMock(); + $factory + ->expects($this->once()) + ->method('__invoke') + ->will($this->returnValue($loop)); + + GlobalLoop::setFactory($factory); + + $this->assertSame($loop, GlobalLoop::get()); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage The GlobalLoop factory must return an instance of LoopInterface but returned NULL. + */ + public function testThrowsExceptionWhenFactoryDoesNotReturnALoopInterface() + { + $factory = $this->createCallableMock(); + $factory + ->expects($this->once()) + ->method('__invoke'); + + GlobalLoop::setFactory($factory); + + GlobalLoop::get(); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Setting a factory after the global loop has been started is not allowed. + */ + public function testThrowsExceptionWhenSettingAFactoryAfterLoopIsCreated() + { + GlobalLoop::get()->run(); + + GlobalLoop::setFactory(null); + } +} From 4d5e850f6bdfdd9e6a4de0807dfddc36ae7d7e00 Mon Sep 17 00:00:00 2001 From: Jan Sorgalla Date: Sat, 11 Mar 2017 10:56:49 +0100 Subject: [PATCH 2/2] Automatically run global loop in a shutdown function --- src/GlobalLoop.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/GlobalLoop.php b/src/GlobalLoop.php index f95b4f62..d6aad5b3 100644 --- a/src/GlobalLoop.php +++ b/src/GlobalLoop.php @@ -12,6 +12,7 @@ final class GlobalLoop private static $factory; private static $didRun = false; + private static $disableRunOnShutdown = false; public static function setFactory(callable $factory = null) { @@ -24,6 +25,11 @@ public static function setFactory(callable $factory = null) self::$factory = $factory; } + public function disableRunOnShutdown() + { + self::$disableRunOnShutdown = true; + } + /** * @return LoopInterface */ @@ -33,6 +39,14 @@ public static function get() return self::$loop; } + register_shutdown_function(function () { + if (self::$disableRunOnShutdown || self::$didRun || !self::$loop) { + return; + } + + self::$loop->run(); + }); + self::$loop = self::create(); self::$loop->futureTick(function () { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy