From 0dd2eea721e14e6e70ea879b0c28faadb1be76f5 Mon Sep 17 00:00:00 2001 From: m-yamagishi Date: Thu, 19 Oct 2023 04:48:43 +0900 Subject: [PATCH] feat: Add HttpResultInterface --- src/Console/Commands/RunCommand.php | 2 +- src/Contracts/HttpResultInterface.php | 24 +++++++++++++++++++++++ src/Contracts/ReporterInterface.php | 2 +- src/HttpClient/AmphpClient.php | 6 ++++-- src/HttpClient/HttpResult.php | 28 ++++++++++++++------------- src/Reporters/TableReporter.php | 1 - 6 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 src/Contracts/HttpResultInterface.php diff --git a/src/Console/Commands/RunCommand.php b/src/Console/Commands/RunCommand.php index 1a7df17..2b9e402 100644 --- a/src/Console/Commands/RunCommand.php +++ b/src/Console/Commands/RunCommand.php @@ -139,7 +139,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $io->writeln(\sprintf('Start execution at %s', \date('Y-m-d H:i:s'))); foreach ($executor->execute($this->cancelToken) as $_) { - // Do nothing + // TODO: add progress } $io->writeln( diff --git a/src/Contracts/HttpResultInterface.php b/src/Contracts/HttpResultInterface.php new file mode 100644 index 0000000..688ad76 --- /dev/null +++ b/src/Contracts/HttpResultInterface.php @@ -0,0 +1,24 @@ +>> + * @template-extends IteratorAggregate<'request'|'response'|'requestException'|'uncaughtException', ?array>> + */ +interface HttpResultInterface extends ArrayAccess, JsonSerializable, Stringable, IteratorAggregate +{ +} diff --git a/src/Contracts/ReporterInterface.php b/src/Contracts/ReporterInterface.php index 10c1f75..41e8d38 100644 --- a/src/Contracts/ReporterInterface.php +++ b/src/Contracts/ReporterInterface.php @@ -16,7 +16,7 @@ interface ReporterInterface /** * Reports HTTP profiling results * - * @param array $results + * @param HttpResultInterface[] $results * @return void */ public function report(array $results): void; diff --git a/src/HttpClient/AmphpClient.php b/src/HttpClient/AmphpClient.php index abe9091..3897d7d 100644 --- a/src/HttpClient/AmphpClient.php +++ b/src/HttpClient/AmphpClient.php @@ -74,16 +74,18 @@ private function handle(RequestInterface $request): ResponseInterface try { $ampResponse = $this->client->request($ampRequest, $this->cancellation); + $psrResponse = $this->toPsrResponse($ampResponse); + // Profiles with HTTP events. $this->profiler->profile($ampRequest, $ampResponse); + + return $psrResponse; } catch (\Throwable $exception) { // Profile exception during request $this->profiler->profileException($ampRequest, $exception); throw new RequestException('failed to fetch response', previous: $exception); } - - return $this->toPsrResponse($ampResponse); } /** diff --git a/src/HttpClient/HttpResult.php b/src/HttpClient/HttpResult.php index da8a47f..f66de30 100644 --- a/src/HttpClient/HttpResult.php +++ b/src/HttpClient/HttpResult.php @@ -10,17 +10,16 @@ use Amp\Http\Client\Request; use Amp\Http\Client\Response; -use ArrayAccess; -use JsonSerializable; -use Stringable; +use ArrayIterator; +use Heavyrain\Contracts\HttpResultInterface; use Throwable; +use Traversable; /** * HTTP profiling result * for reduce memory and reference leaks, all data is stored in array - * @template-implements ArrayAccess */ -final class HttpResult implements ArrayAccess, JsonSerializable, Stringable +final class HttpResult implements HttpResultInterface { public const START_KEY = 'start'; public const CONNECT_KEY = 'connect'; @@ -47,25 +46,28 @@ public function __construct( public function offsetExists(mixed $offset): bool { - return \in_array($offset, ['request', 'response', 'request_exception', 'uncaught_exception'], true); + return \array_key_exists($offset, $this->result); } public function offsetGet(mixed $offset): mixed { if (!\array_key_exists($offset, $this->result)) { - throw new \RuntimeException('invalid offset. supported: request, response, request_exception, uncaught_exception'); + throw new \RuntimeException('invalid offset. supported: request, response, requestException, uncaughtException'); } return $this->result[$offset]; } - public function offsetSet(mixed $offset, mixed $value): void - { - throw new \LogicException('cannot set result after created'); + public function offsetSet(mixed $offset, mixed $value): void { + throw new \LogicException('HttpResult is immutable'); + } + + public function offsetUnset(mixed $offset): void { + throw new \LogicException('HttpResult is immutable'); } - public function offsetUnset(mixed $offset): void + public function getIterator(): Traversable { - throw new \LogicException('cannot unset result after created'); + return new ArrayIterator($this->result); } public function jsonSerialize(): mixed @@ -173,7 +175,7 @@ private static function convertException(Throwable $exception): array 'class' => \get_class($exception), 'message' => $exception->getMessage(), 'code' => $exception->getCode(), - 'previousMessage' => $exception->getPrevious() ? $exception->getPrevious()->getMessage() : null, + 'previousMessage' => $exception->getPrevious()?->getMessage(), ]; } } diff --git a/src/Reporters/TableReporter.php b/src/Reporters/TableReporter.php index ffe94c5..d671be9 100644 --- a/src/Reporters/TableReporter.php +++ b/src/Reporters/TableReporter.php @@ -20,7 +20,6 @@ public function __construct(private readonly SymfonyStyle $io) public function report(array $results): void { $rows = []; - /** @var \Heavyrain\HttpClient\HttpResult $result */ foreach ($results as $result) { $rows[] = [ 'request' => \json_encode($result['request']),