diff --git a/.php_cs b/.php_cs index afcb974..5abf409 100644 --- a/.php_cs +++ b/.php_cs @@ -1,12 +1,12 @@ =5.4", + "symfony/polyfill-php56": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "SuperClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia", + "role": "Developer" + } + ], + "description": "Serialize Closure objects, including their context and binding", + "homepage": "https://github.com/jeremeamia/super_closure", + "keywords": [ + "closure", + "function", + "lambda", + "parser", + "serializable", + "serialize", + "tokenizer" + ], + "time": "2018-03-21T22:21:57+00:00" + }, { "name": "justinrainbow/json-schema", "version": "5.2.7", @@ -2033,6 +2128,149 @@ ], "time": "2018-02-15T16:58:55+00:00" }, + { + "name": "php-di/invoker", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/Invoker.git", + "reference": "540c27c86f663e20fe39a24cd72fa76cdb21d41a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/540c27c86f663e20fe39a24cd72fa76cdb21d41a", + "reference": "540c27c86f663e20fe39a24cd72fa76cdb21d41a", + "shasum": "" + }, + "require": { + "psr/container": "~1.0" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "phpunit/phpunit": "~4.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Invoker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Generic and extensible callable invoker", + "homepage": "https://github.com/PHP-DI/Invoker", + "keywords": [ + "callable", + "dependency", + "dependency-injection", + "injection", + "invoke", + "invoker" + ], + "time": "2017-03-20T19:28:22+00:00" + }, + { + "name": "php-di/php-di", + "version": "6.0.5", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PHP-DI.git", + "reference": "5e8b809960d5c3bfa096a90da9a78650e80b1f0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/5e8b809960d5c3bfa096a90da9a78650e80b1f0e", + "reference": "5e8b809960d5c3bfa096a90da9a78650e80b1f0e", + "shasum": "" + }, + "require": { + "jeremeamia/superclosure": "^2.0", + "nikic/php-parser": "^2.0|^3.0|^4.0", + "php": ">=7.0.0", + "php-di/invoker": "^2.0", + "php-di/phpdoc-reader": "^2.0.1", + "psr/container": "^1.0" + }, + "provide": { + "psr/container-implementation": "^1.0" + }, + "require-dev": { + "doctrine/annotations": "~1.2", + "friendsofphp/php-cs-fixer": "^2.4", + "mnapoli/phpunit-easymock": "~1.0", + "ocramius/proxy-manager": "~2.0.2", + "phpstan/phpstan": "^0.9.2", + "phpunit/phpunit": "~6.4" + }, + "suggest": { + "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", + "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~2.0)" + }, + "type": "library", + "autoload": { + "psr-4": { + "DI\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The dependency injection container for humans", + "homepage": "http://php-di.org/", + "keywords": [ + "PSR-11", + "container", + "container-interop", + "dependency injection", + "di", + "ioc", + "psr11" + ], + "time": "2018-09-17T15:34:44+00:00" + }, + { + "name": "php-di/phpdoc-reader", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PhpDocReader.git", + "reference": "7d0de60b9341933c8afd172a6255cd7557601e0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/7d0de60b9341933c8afd172a6255cd7557601e0e", + "reference": "7d0de60b9341933c8afd172a6255cd7557601e0e", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpDocReader\\": "src/PhpDocReader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", + "keywords": [ + "phpdoc", + "reflection" + ], + "time": "2018-02-18T17:39:01+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "1.0.1", @@ -3647,6 +3885,62 @@ ], "time": "2018-08-06T14:22:27+00:00" }, + { + "name": "symfony/polyfill-php56", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "ff208829fe1aa48ab9af356992bb7199fed551af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/ff208829fe1aa48ab9af356992bb7199fed551af", + "reference": "ff208829fe1aa48ab9af356992bb7199fed551af", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-09-21T06:26:08+00:00" + }, { "name": "symfony/polyfill-php70", "version": "v1.9.0", @@ -3761,6 +4055,58 @@ ], "time": "2018-08-06T14:22:27+00:00" }, + { + "name": "symfony/polyfill-util", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "3b58903eae668d348a7126f999b0da0f2f93611c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/3b58903eae668d348a7126f999b0da0f2f93611c", + "reference": "3b58903eae668d348a7126f999b0da0f2f93611c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ], + "time": "2018-09-30T16:36:12+00:00" + }, { "name": "symfony/process", "version": "v4.1.6", @@ -4011,7 +4357,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "wyrihaximus/react-redis-waiting-client": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/etc/di/redis-client.php b/etc/di/redis-client.php index 67c50b3..239cc54 100644 --- a/etc/di/redis-client.php +++ b/etc/di/redis-client.php @@ -1,13 +1,15 @@ - \DI\factory(function (LoopInterface $loop, string $dsn, LoggerInterface $logger = null) { + Client::class => factory(function (LoopInterface $loop, string $dsn, LoggerInterface $logger = null) { return WaitingClient::create($loop, $dsn, $logger); }) - ->parameter('dsn', \DI\get('config.redis.dsn')), + ->parameter('dsn', get('config.redis.dsn')), ]; diff --git a/src/WaitingClient.php b/src/WaitingClient.php deleted file mode 100644 index f3ee080..0000000 --- a/src/WaitingClient.php +++ /dev/null @@ -1,86 +0,0 @@ -callQueue = new \SplQueue(); - $logger->debug('Connecting'); - $factory->createClient($dsn)->done(function (Client $client) use ($logger) { - $logger->debug('Connected'); - $this->redis = $client; - - $logger->debug('Executing ' . $this->callQueue->count() . ' waiting call(s)'); - while ($this->callQueue->count() > 0) { - $call = $this->callQueue->dequeue(); - $name = $call['name']; - $args = $call['args']; - $call['deferred']->resolve($this->redis->$name(...$args)); - } - $logger->debug('Executed all waiting calls, any new calls will be send to Redis directly'); - }, CallableThrowableLogger::create($logger)); - } - - public function __call($name, $args) - { - if ($this->redis instanceof Client) { - return $this->redis->$name(...$args); - } - - $deferred = new Deferred(); - - $this->callQueue->enqueue([ - 'deferred' => $deferred, - 'name' => $name, - 'args' => $args, - ]); - - return $deferred->promise(); - } - - public static function create(LoopInterface $loop, string $dsn, LoggerInterface $logger = null): self - { - return new self(new Factory($loop), $dsn, $logger ?? new NullLogger()); - } - - public function end() - { - // TODO: Implement end() method. - } - - public function close() - { - // TODO: Implement close() method. - } -} diff --git a/tests/DiTest.php b/tests/DiTest.php new file mode 100644 index 0000000..7a91cd4 --- /dev/null +++ b/tests/DiTest.php @@ -0,0 +1,35 @@ +prophesize(LoopInterface::class); + + $logger = $this->prophesize(LoggerInterface::class); + $logger->debug('Connecting')->shouldBeCalled(); + $logger->debug('Connected')->shouldNotBeCalled(); + $logger->debug('Executing 0 waiting call(s)')->shouldNotBeCalled(); + $logger->debug('Executed all waiting calls, any new calls will be send to Redis directly')->shouldNotBeCalled(); + + $di = require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'di' . DIRECTORY_SEPARATOR . 'redis-client.php'; + $container = new Container(); + $container->set(Client::class, $di[Client::class]); + $container->set(LoopInterface::class, $loop->reveal()); + $container->set(LoggerInterface::class, $logger->reveal()); + $container->set('config.redis.dsn', self::DSN); + $client = $container->get(Client::class); + + self::assertInstanceOf(Client::class, $client); + } +} diff --git a/tests/RedisClient.php b/tests/RedisClient.php deleted file mode 100644 index 70133fc..0000000 --- a/tests/RedisClient.php +++ /dev/null @@ -1,30 +0,0 @@ -prophesize(LoopInterface::class); - - $logger = $this->prophesize(LoggerInterface::class); - $logger->debug('Connecting')->shouldBeCalled(); - $logger->debug('Connected')->shouldNotBeCalled(); - $logger->debug('Executing 0 waiting call(s)')->shouldNotBeCalled(); - $logger->debug('Executed all waiting calls, any new calls will be send to Redis directly')->shouldNotBeCalled(); - - WaitingClient::create($loop->reveal(), self::DSN, $logger->reveal()); - } - - public function testLogging() - { - $logger = $this->prophesize(LoggerInterface::class); - $logger->debug('Connecting')->shouldBeCalled(); - $logger->debug('Connected')->shouldBeCalled(); - $logger->debug('Executing 0 waiting call(s)')->shouldBeCalled(); - $logger->debug('Executed all waiting calls, any new calls will be send to Redis directly')->shouldBeCalled(); - - $redisFactory = $this->prophesize(Factory::class); - $redisFactory->createClient(self::DSN)->shouldbeCalled()->willReturn(resolve($this->prophesize(Client::class)->reveal())); - - new WaitingClient($redisFactory->reveal(), self::DSN, $logger->reveal()); - } - - public function testCalls() - { - $logger = $this->prophesize(LoggerInterface::class); - $logger->debug(Argument::type('string'))->shouldBeCalled(); - $logger->debug('Executing 1 waiting call(s)')->shouldBeCalled(); - - $deferred = new Deferred(); - - $redis = $this->prophesize(RedisClient::class); - $redis->incr('key')->shouldBeCalled()->willReturn(resolve(true)); - $redis->incr('sleutel')->shouldBeCalled()->willReturn(resolve(true)); - - $redisFactory = $this->prophesize(Factory::class); - $redisFactory->createClient(self::DSN)->shouldbeCalled()->willReturn($deferred->promise()); - - $waitingClient = new WaitingClient($redisFactory->reveal(), self::DSN, $logger->reveal()); - - $waitingClient->incr('key'); - - $deferred->resolve($redis->reveal()); - - $waitingClient->incr('sleutel'); - } -}