From 69b003260cf16e4ba27cae7b38fd1109b700662c Mon Sep 17 00:00:00 2001 From: Mathieu Ledru Date: Thu, 7 Sep 2023 00:22:20 +0200 Subject: [PATCH] :sparkles: Add Flow\Driver\RevoltDriver --- CHANGELOG.md | 1 + composer.json | 6 ++- examples/flow.php | 6 ++- examples/server.php | 6 ++- src/Driver/AmpDriver.php | 32 ++--------- src/Driver/RevoltDriver.php | 89 +++++++++++++++++++++++++++++++ tests/Driver/AmpDriverTest.php | 11 ++++ tests/Driver/RevoltDriverTest.php | 16 ++++++ tests/Flow/FlowTrait.php | 2 + 9 files changed, 136 insertions(+), 33 deletions(-) create mode 100644 src/Driver/RevoltDriver.php create mode 100644 tests/Driver/RevoltDriverTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d696ce3..501807a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v1.1.x +- Add Flow\Driver\RevoltDriver - Add more quality tools from https://github.com/IngeniozIT/php-skeleton ## v1.1.3 diff --git a/composer.json b/composer.json index f3d650ea..4de15f5f 100644 --- a/composer.json +++ b/composer.json @@ -28,13 +28,15 @@ "react/async": "^4.1", "symfony/doctrine-messenger": "^6.3", "symfony/messenger": "^6.3", - "symfony/orm-pack": "^2.4" + "symfony/orm-pack": "^2.4", + "revolt/event-loop": "^1.0" }, "suggest": { "amphp/amp": "Provide asynchronous with AMP", "ext-openswoole": "Provide asynchronous with OpenSwoole", "react/async": "Provide asynchronous with ReactPHP", - "symfony/messenger": "Provide symfony messenger support" + "symfony/messenger": "Provide symfony messenger support", + "revolt/event-loop": "Provide asynchronous with Revolt" }, "autoload": { "psr-4": { diff --git a/examples/flow.php b/examples/flow.php index 79928feb..71b06d52 100644 --- a/examples/flow.php +++ b/examples/flow.php @@ -7,16 +7,18 @@ use Flow\Driver\AmpDriver; use Flow\Driver\FiberDriver; use Flow\Driver\ReactDriver; +use Flow\Driver\RevoltDriver; use Flow\Driver\SwooleDriver; use Flow\Flow\Flow; use Flow\Ip; use Flow\IpStrategy\MaxIpStrategy; -$driver = match (random_int(1, 4)) { +$driver = match (random_int(1, 5)) { 1 => new AmpDriver(), 2 => new ReactDriver(), 3 => new FiberDriver(), - 4 => new SwooleDriver(), + 4 => new RevoltDriver(), + 5 => new SwooleDriver(), }; printf("Use %s\n", $driver::class); diff --git a/examples/server.php b/examples/server.php index 168eaad5..4ab3c466 100644 --- a/examples/server.php +++ b/examples/server.php @@ -8,17 +8,19 @@ use Flow\Driver\AmpDriver; use Flow\Driver\FiberDriver; use Flow\Driver\ReactDriver; +use Flow\Driver\RevoltDriver; use Flow\Driver\SwooleDriver; use Flow\Examples\Transport\DoctrineIpTransport; use Flow\Flow\Flow; use Flow\Flow\TransportFlow; use Flow\IpStrategy\MaxIpStrategy; -$driver = match (random_int(1, 4)) { +$driver = match (random_int(1, 5)) { 1 => new AmpDriver(), 2 => new ReactDriver(), 3 => new FiberDriver(), - 4 => new SwooleDriver(), + 4 => new RevoltDriver(), + 5 => new SwooleDriver(), }; printf("Use %s\n", $driver::class); diff --git a/src/Driver/AmpDriver.php b/src/Driver/AmpDriver.php index a1325cc5..99e9f840 100644 --- a/src/Driver/AmpDriver.php +++ b/src/Driver/AmpDriver.php @@ -11,13 +11,12 @@ use RuntimeException; use Throwable; +use function Amp\async; use function Amp\delay; use function function_exists; class AmpDriver implements DriverInterface { - private int $counter = 0; - public function __construct() { if (!function_exists('Amp\\async')) { @@ -27,8 +26,8 @@ public function __construct() public function async(Closure $callback, Closure $onResolve = null): Closure { - return function (...$args) use ($callback, $onResolve): void { - EventLoop::queue(function (Closure $callback, array $args, Closure $onResolve = null) { + return static function (...$args) use ($callback, $onResolve): void { + async(static function (Closure $callback, array $args, Closure $onResolve = null) { try { $return = $callback(...$args, ...($args = [])); if ($onResolve) { @@ -38,11 +37,8 @@ public function async(Closure $callback, Closure $onResolve = null): Closure if ($onResolve) { $onResolve(new Exception($exception->getMessage(), $exception->getCode(), $exception)); } - } finally { - $this->pop(); } - }, $callback, $args, $onResolve); - $this->push(); + }, $callback, $args, $onResolve)->await(); }; } @@ -54,27 +50,9 @@ public function delay(float $seconds): void public function tick(int $interval, Closure $callback): Closure { $tickId = EventLoop::repeat($interval / 1000, $callback); - $this->push(); - return function () use ($tickId) { + return static function () use ($tickId) { EventLoop::cancel($tickId); - $this->pop(); }; } - - private function push(): void - { - if (/* $this->counter === 0 || */ !EventLoop::getDriver()->isRunning()) { - EventLoop::run(); - } - $this->counter++; - } - - private function pop(): void - { - $this->counter--; - if ($this->counter === 0) { - EventLoop::getDriver()->stop(); - } - } } diff --git a/src/Driver/RevoltDriver.php b/src/Driver/RevoltDriver.php new file mode 100644 index 00000000..dad0f1e8 --- /dev/null +++ b/src/Driver/RevoltDriver.php @@ -0,0 +1,89 @@ +getMessage(), $exception->getCode(), $exception)); + } + } finally { + $this->pop(); + } + }, $callback, $args, $onResolve); + $this->push(); + }; + } + + public function delay(float $seconds): void + { + $suspension = EventLoop::getSuspension(); + $callbackId = EventLoop::delay($seconds, static fn () => $suspension->resume()); + + try { + $suspension->suspend(); + } finally { + EventLoop::cancel($callbackId); + } + } + + public function tick(int $interval, Closure $callback): Closure + { + $tickId = EventLoop::repeat($interval / 1000, $callback); + $this->push(); + + return function () use ($tickId) { + EventLoop::cancel($tickId); + $this->pop(); + }; + } + + private function push(): void + { + if (/* $this->counter === 0 || */ !EventLoop::getDriver()->isRunning()) { + EventLoop::run(); + } + $this->counter++; + } + + private function pop(): void + { + $this->counter--; + if ($this->counter === 0) { + EventLoop::getDriver()->stop(); + } + } +} diff --git a/tests/Driver/AmpDriverTest.php b/tests/Driver/AmpDriverTest.php index bbe98cf5..5cee2580 100644 --- a/tests/Driver/AmpDriverTest.php +++ b/tests/Driver/AmpDriverTest.php @@ -6,9 +6,20 @@ use Flow\Driver\AmpDriver; use Flow\DriverInterface; +use Revolt\EventLoop; class AmpDriverTest extends DriverTestCase { + protected function setUp(): void + { + EventLoop::getDriver()->run(); + } + + protected function tearDown(): void + { + EventLoop::getDriver()->stop(); + } + protected function createDriver(): DriverInterface { return new AmpDriver(); diff --git a/tests/Driver/RevoltDriverTest.php b/tests/Driver/RevoltDriverTest.php new file mode 100644 index 00000000..ddcd7b29 --- /dev/null +++ b/tests/Driver/RevoltDriverTest.php @@ -0,0 +1,16 @@ + fn (): AmpDriver => new AmpDriver(), // 'fiber' => fn (): FiberDriver => new FiberDriver(), 'react' => static fn (): ReactDriver => new ReactDriver(), + // 'revolt' => static fn (): RevoltDriver => new RevoltDriver(), // 'swoole' => fn (): SwooleDriver => new SwooleDriver(), ];