diff --git a/composer.json b/composer.json index 54b4bfe..f3c3e13 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ ], "require": { "php": "^7.0", - "api-clients/middleware": "^2.0" + "api-clients/middleware": "^4.0" }, "require-dev": { "api-clients/test-utilities": "^4.1", diff --git a/composer.lock b/composer.lock index 23197ca..aa9821d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,38 +4,40 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "651dd1d98557694adb538713f84570e9", + "content-hash": "9f0b000ef839a43a1e5e00824f4c5916", "packages": [ { "name": "api-clients/middleware", - "version": "2.0.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/php-api-clients/middleware.git", - "reference": "e25852d9d4d3092cc657b7660a413f6e73ea8c4d" + "reference": "328f8e17bbf5a51107de0d1b5987c04757f66499" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-api-clients/middleware/zipball/e25852d9d4d3092cc657b7660a413f6e73ea8c4d", - "reference": "e25852d9d4d3092cc657b7660a413f6e73ea8c4d", + "url": "https://api.github.com/repos/php-api-clients/middleware/zipball/328f8e17bbf5a51107de0d1b5987c04757f66499", + "reference": "328f8e17bbf5a51107de0d1b5987c04757f66499", "shasum": "" }, "require": { + "doctrine/annotations": "^1.4", "php": "^7.0", "psr/http-message": "^1.0", - "react/promise": "^2.4" + "react/promise": "^2.4", + "wyrihaximus/doctrine-annotation-autoloader": "^1.0" }, "require-dev": { - "api-clients/test-utilities": "^3.0", - "container-interop/container-interop": "^1.1", - "guzzlehttp/psr7": "^1.3" + "api-clients/test-utilities": "^4.1", + "guzzlehttp/psr7": "^1.3", + "psr/container": "^1.0" }, "suggest": { "api-clients/middleware-cache": "Cache requests with different strategies", "api-clients/middleware-log": "Log requests and their context", "api-clients/middleware-oauth1": "Sign requests with oauth1", "api-clients/middleware-pool": "Pool the maximum concurrent requests", - "container-interop/container-interop": "Add a ContainerInterface implementation to use the ContainerLocator" + "psr/container": "Add a ContainerInterface implementation to use the ContainerLocator" }, "type": "library", "autoload": { @@ -54,7 +56,129 @@ } ], "description": "Request middleware", - "time": "2017-04-08T07:00:13+00:00" + "time": "2017-06-28T19:24:19+00:00" + }, + { + "name": "doctrine/annotations", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-02-24T16:22:25+00:00" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" }, { "name": "psr/http-message", @@ -151,6 +275,42 @@ "promises" ], "time": "2017-03-25T12:08:31+00:00" + }, + { + "name": "wyrihaximus/doctrine-annotation-autoloader", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/WyriHaximus/php-doctrine-annotation-autoloader.git", + "reference": "9670f84b7d3ca53723556988080ebc939da345af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WyriHaximus/php-doctrine-annotation-autoloader/zipball/9670f84b7d3ca53723556988080ebc939da345af", + "reference": "9670f84b7d3ca53723556988080ebc939da345af", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + } + ], + "description": "Request middleware", + "time": "2017-06-19T15:02:15+00:00" } ], "packages-dev": [ @@ -244,74 +404,6 @@ ], "time": "2016-03-09T15:10:22+00:00" }, - { - "name": "doctrine/annotations", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", - "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2017-02-24T16:22:25+00:00" - }, { "name": "doctrine/instantiator", "version": "1.0.5", @@ -366,60 +458,6 @@ ], "time": "2015-06-14T21:17:01+00:00" }, - { - "name": "doctrine/lexer", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "lexer", - "parser" - ], - "time": "2014-09-09T13:34:57+00:00" - }, { "name": "friendsofphp/php-cs-fixer", "version": "v2.3.2", diff --git a/src/Middleware.php b/src/Middleware.php index 227d030..50ae67c 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -2,24 +2,23 @@ namespace ApiClients\Middleware\Timer\Response; -use ApiClients\Foundation\Middleware\ErrorTrait; +use ApiClients\Foundation\Middleware\Annotation\First; +use ApiClients\Foundation\Middleware\Annotation\Last; use ApiClients\Foundation\Middleware\MiddlewareInterface; -use ApiClients\Foundation\Middleware\Priority; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use React\Promise\CancellablePromiseInterface; +use Throwable; use function React\Promise\resolve; final class Middleware implements MiddlewareInterface { - use ErrorTrait; - const HEADER = 'X-Middleware-Timer-Response'; /** - * @var float + * @var float[] */ - private $time; + private $times; /** * Return the processed $request via a fulfilled promise. @@ -27,12 +26,18 @@ final class Middleware implements MiddlewareInterface * If neither is possible, e.g. on some kind of failure, resolve the unaltered request. * * @param RequestInterface $request + * @param string $transactionId * @param array $options * @return CancellablePromiseInterface + * + * @Last() */ - public function pre(RequestInterface $request, array $options = []): CancellablePromiseInterface - { - $this->time = microtime(true); + public function pre( + RequestInterface $request, + string $transactionId, + array $options = [] + ): CancellablePromiseInterface { + $this->times[$transactionId] = microtime(true); return resolve($request); } @@ -41,24 +46,34 @@ public function pre(RequestInterface $request, array $options = []): Cancellable * Return the processed $response via a promise. * * @param ResponseInterface $response + * @param string $transactionId * @param array $options * @return CancellablePromiseInterface + * + * @First() */ - public function post(ResponseInterface $response, array $options = []): CancellablePromiseInterface - { - $time = microtime(true) - $this->time; + public function post( + ResponseInterface $response, + string $transactionId, + array $options = [] + ): CancellablePromiseInterface { + $time = microtime(true) - $this->times[$transactionId]; + unset($this->times[$transactionId]); return resolve($response->withAddedHeader(self::HEADER, (string)$time)); } /** - * Priority ranging from 0 to 1000. Where 1000 will be executed first on `pre` and 0 last on `pre`. - * For `post` the order is reversed. - * - * @return int + * @param Throwable $throwable + * @param string $transactionId + * @param array $options + * @return CancellablePromiseInterface */ - public function priority(): int - { - return Priority::FIRST; + public function error( + Throwable $throwable, + string $transactionId, + array $options = [] + ): CancellablePromiseInterface { + unset($this->times[$transactionId]); } } diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 5898acc..bff550c 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -13,13 +13,16 @@ final class MiddlewareTest extends TestCase { public function testPost() { + $idA = 'Abc'; + $idB = 'aBc'; $response = new Response(200, []); $middleware = new Middleware(); - $middleware->pre(new Request('GET', 'https://example.com/')); - $responseObject = await($middleware->post($response), Factory::create()); + $middleware->pre(new Request('GET', 'https://example.com/'), $idA, []); + $middleware->pre(new Request('GET', 'https://example.com/'), $idB, []); + $responseObject = await($middleware->post($response, $idA, []), Factory::create()); self::assertTrue((float)$responseObject->getHeaderLine(Middleware::HEADER) < 1); sleep(1); - $responseObject = await($middleware->post($response), Factory::create()); + $responseObject = await($middleware->post($response, $idB, []), Factory::create()); self::assertTrue((float)$responseObject->getHeaderLine(Middleware::HEADER) > 1); } }