Skip to content

Commit

Permalink
✨ Add Flow\Driver\RevoltDriver
Browse files Browse the repository at this point in the history
  • Loading branch information
matyo91 committed Sep 6, 2023
1 parent 666ad6e commit 69b0032
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
6 changes: 4 additions & 2 deletions examples/flow.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 4 additions & 2 deletions examples/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
32 changes: 5 additions & 27 deletions src/Driver/AmpDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')) {
Expand All @@ -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) {
Expand All @@ -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();
};
}

Expand All @@ -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();
}
}
}
89 changes: 89 additions & 0 deletions src/Driver/RevoltDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

declare(strict_types=1);

namespace Flow\Driver;

use Closure;
use Flow\DriverInterface;
use Flow\Exception;
use Revolt\EventLoop;
use Revolt\EventLoop\Driver;
use RuntimeException;
use Throwable;

class RevoltDriver implements DriverInterface
{
private int $counter = 0;

public function __construct(Driver $driver = null)
{
if (!class_exists('Revolt\\EventLoop')) {
throw new RuntimeException('Revolt is not loaded. Suggest install it with composer require revolt/event-loop');
}

if ($driver !== null) {
EventLoop::setDriver($driver);
}
}

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) {
try {
$return = $callback(...$args, ...($args = []));
if ($onResolve) {
$onResolve($return);
}
} catch (Throwable $exception) {
if ($onResolve) {
$onResolve(new Exception($exception->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();
}
}
}
11 changes: 11 additions & 0 deletions tests/Driver/AmpDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
16 changes: 16 additions & 0 deletions tests/Driver/RevoltDriverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Flow\Test\Driver;

use Flow\Driver\RevoltDriver;
use Flow\DriverInterface;

class RevoltDriverTest extends DriverTestCase
{
protected function createDriver(): DriverInterface
{
return new RevoltDriver();
}
}
2 changes: 2 additions & 0 deletions tests/Flow/FlowTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Flow\Driver\AmpDriver;
use Flow\Driver\FiberDriver;
use Flow\Driver\ReactDriver;
use Flow\Driver\RevoltDriver;
use Flow\Driver\SwooleDriver;
use Flow\IpStrategy\LinearIpStrategy;
use Flow\IpStrategy\MaxIpStrategy;
Expand All @@ -24,6 +25,7 @@ protected static function matrix(Closure $datas): array
// 'amp' => 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(),
];

Expand Down

0 comments on commit 69b0032

Please sign in to comment.