From 5f81c179af29ca31ec17e66309fc879997029a7b Mon Sep 17 00:00:00 2001 From: Valentin V / vvval Date: Tue, 21 Apr 2020 17:57:00 +0300 Subject: [PATCH 1/3] #39 relay factory --- php-src/Relay.php | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 php-src/Relay.php diff --git a/php-src/Relay.php b/php-src/Relay.php new file mode 100644 index 0000000..f2bbb71 --- /dev/null +++ b/php-src/Relay.php @@ -0,0 +1,43 @@ + Date: Tue, 21 Apr 2020 20:07:03 +0300 Subject: [PATCH 2/3] #39 Add relay factory --- php-src/Exceptions/RelayFactoryException.php | 12 +++ php-src/Relay.php | 48 ++++++----- tests/Cases/RelayFactoryTest.php | 91 ++++++++++++++++++++ 3 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 php-src/Exceptions/RelayFactoryException.php create mode 100644 tests/Cases/RelayFactoryTest.php diff --git a/php-src/Exceptions/RelayFactoryException.php b/php-src/Exceptions/RelayFactoryException.php new file mode 100644 index 0000000..d5968eb --- /dev/null +++ b/php-src/Exceptions/RelayFactoryException.php @@ -0,0 +1,12 @@ +[^:\/]+):\/\/(?P[^:]+)(:(?P[^:]+))?/'; + public static function create(string $connection): RelayInterface { - $parsed = self::detectProtocol($connection); - if ($parsed === null) { - throw new Exceptions\RelayException('unknown connection'); + if (!preg_match(self::CONNECTION, strtolower($connection), $match)) { + throw new Exceptions\RelayFactoryException('unsupported connection format'); } - [$protocol, $etc] = $parsed; - - } - - private static function detectProtocol(string $connection) - { - $connection = strtolower($connection); - if (mb_strpos($connection, '://') === false) { - return null; + switch ($match['protocol']) { + case self::TCP_SOCKET: + //fall through + case self::UNIX_SOCKET: + return new SocketRelay( + $match['arg1'], + isset($match['arg2']) ? (int)$match['arg2'] : null, + $match['protocol'] === self::TCP_SOCKET ? SocketRelay::SOCK_TCP : SocketRelay::SOCK_UNIX + ); + + case self::STREAM: + if (!isset($match['arg2'])) { + throw new Exceptions\RelayFactoryException('unsupported stream connection format'); + } + + return new StreamRelay( + fopen("php://{$match['arg1']}", 'rb'), + fopen("php://{$match['arg2']}", 'wb') + ); + default: + throw new Exceptions\RelayFactoryException('unknown connection protocol'); } - - return explode('://', $connection, 2); - } - - private static function createTCP(string $connection): SocketRelay - { - } - private static function createUnix(string $connection): SocketRelay - { } } diff --git a/tests/Cases/RelayFactoryTest.php b/tests/Cases/RelayFactoryTest.php new file mode 100644 index 0000000..e2786bd --- /dev/null +++ b/tests/Cases/RelayFactoryTest.php @@ -0,0 +1,91 @@ +assertTrue(true); + if ($expectedException) { + $this->expectException(Exceptions\RelayFactoryException::class); + } + + try { + Relay::create($connection); + } catch (Exceptions\RelayFactoryException $exception) { + throw $exception; + } catch (Throwable $exception) { + //do nothing, that's not a factory issue + } + } + + /** + * @return iterable + */ + public function formatProvider(): iterable + { + return [ + //format invalid + ['tcp:localhost:', true], + ['tcp:/localhost:', true], + ['tcp//localhost:', true], + ['tcp//localhost', true], + //unknown provider + ['test://localhost', true], + //pipes require 2 args + ['pipes://localhost:', true], + ['pipes://localhost', true], + //valid format + ['tcp://localhost'], + ['tcp://localhost:123'], + ['unix://localhost:123'], + ['tcp://localhost:abc'], + ['pipes://stdin:stdout'], + ]; + } + + public function testTCP(): void + { + /** @var SocketRelay $relay */ + $relay = Relay::create('tcp://localhost:0'); + $this->assertInstanceOf(SocketRelay::class, $relay); + $this->assertSame('localhost', $relay->getAddress()); + $this->assertSame(0, $relay->getPort()); + $this->assertSame(SocketRelay::SOCK_TCP, $relay->getType()); + } + + public function testUnix(): void + { + /** @var SocketRelay $relay */ + $relay = Relay::create('unix://localhost:123'); + $this->assertInstanceOf(SocketRelay::class, $relay); + $this->assertSame('localhost', $relay->getAddress()); + $this->assertSame(SocketRelay::SOCK_UNIX, $relay->getType()); + } + + public function testPipes(): void + { + /** @var StreamRelay $relay */ + $relay = Relay::create('pipes://stdin:stdout'); + $this->assertInstanceOf(StreamRelay::class, $relay); + } +} From f394cebe65309df4ae6720636d90456dc515411e Mon Sep 17 00:00:00 2001 From: Valentin V / vvval Date: Tue, 21 Apr 2020 20:22:33 +0300 Subject: [PATCH 3/3] #39 Update README.md and tests --- README.md | 5 +++++ tests/Cases/RelayFactoryTest.php | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a654077..03c9d9e 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,14 @@ use Spiral\Goridge; require "vendor/autoload.php"; $rpc = new Goridge\RPC(new Goridge\SocketRelay("127.0.0.1", 6001)); +//or, using factory: +$tcpRPC = Goridge\Relay::create('tcp://127.0.0.1:6001'); +$unixRPC = Goridge\Relay::create('unix:///tmp/rpc.sock'); +$streamRPC = Goridge\Relay::create('pipes://stdin:stdout'); echo $rpc->call("App.Hi", "Antony"); ``` +> Factory applies the next format: `://:` ```go package main diff --git a/tests/Cases/RelayFactoryTest.php b/tests/Cases/RelayFactoryTest.php index e2786bd..36bf9ff 100644 --- a/tests/Cases/RelayFactoryTest.php +++ b/tests/Cases/RelayFactoryTest.php @@ -58,6 +58,8 @@ public function formatProvider(): iterable ['tcp://localhost'], ['tcp://localhost:123'], ['unix://localhost:123'], + ['unix://rpc.sock'], + ['unix:///tmp/rpc.sock'], ['tcp://localhost:abc'], ['pipes://stdin:stdout'], ]; @@ -76,9 +78,9 @@ public function testTCP(): void public function testUnix(): void { /** @var SocketRelay $relay */ - $relay = Relay::create('unix://localhost:123'); + $relay = Relay::create('unix:///tmp/rpc.sock'); $this->assertInstanceOf(SocketRelay::class, $relay); - $this->assertSame('localhost', $relay->getAddress()); + $this->assertSame('/tmp/rpc.sock', $relay->getAddress()); $this->assertSame(SocketRelay::SOCK_UNIX, $relay->getType()); }