From 8abcb5f967eda79592b7c417d277609a575cb50e Mon Sep 17 00:00:00 2001 From: Douglas Medeiros Date: Fri, 18 Aug 2023 23:54:33 -0300 Subject: [PATCH 1/2] Corrigido testes e refaturado (#5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: Start application * chore(docs): Styling * fix tests and refactor * chore: Remove unused file Esse arquivo da participação ficaria só na `main`. --------- Co-authored-by: leocavalcante Co-authored-by: Leo Cavalcante Co-authored-by: William Correa --- .env.example | 2 +- app/Consumer/PersonConsumer.php | 10 ++++- app/Controller/PersonController.php | 42 +++++++------------ app/Exception/Handler/AppExceptionHandler.php | 1 + app/Job/PersonJob.php | 20 +++++---- app/Listener/DbQueryExecutedListener.php | 10 ++--- .../ResumeExitCoordinatorListener.php | 1 + app/Model/Model.php | 1 + app/Model/Person.php | 22 +++++----- app/Request/PersonRequest.php | 10 ++--- composer.json | 2 +- config/autoload/dependencies.php | 7 ++++ config/routes.php | 2 + docs/user.rest | 22 ++++++++++ test/Cases/CreatePersonTest.php | 19 +++++---- test/HttpTestCase.php | 22 +++++++--- 16 files changed, 120 insertions(+), 73 deletions(-) create mode 100644 docs/user.rest diff --git a/.env.example b/.env.example index 5ea8b32b..5933a689 100644 --- a/.env.example +++ b/.env.example @@ -11,7 +11,7 @@ DB_CHARSET=utf8mb4 DB_COLLATION=utf8mb4_unicode_ci DB_PREFIX= -REDIS_HOST=localhost +REDIS_HOST=cache REDIS_AUTH=(null) REDIS_PORT=6379 REDIS_DB=0 diff --git a/app/Consumer/PersonConsumer.php b/app/Consumer/PersonConsumer.php index 836b770d..1cf4b445 100644 --- a/app/Consumer/PersonConsumer.php +++ b/app/Consumer/PersonConsumer.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/** + * This file is part of OpenCodeCo. + * + * @link https://github.com/opencodeco/rinha-de-backend-2023-q3 + * @document https://github.com/opencodeco/rinha-de-backend-2023-q3/wiki + * @contact https://github.com/opencodeco/rinha-de-backend-2023-q3/discussions + * @license https://github.com/opencodeco/rinha-de-backend-2023-q3/blob/dev/LICENSE + */ + namespace App\Consumer; use Hyperf\AsyncQueue\Process\ConsumerProcess; @@ -10,5 +19,4 @@ #[Process(name: "async-queue")] class PersonConsumer extends ConsumerProcess { - } \ No newline at end of file diff --git a/app/Controller/PersonController.php b/app/Controller/PersonController.php index cd34d727..3d6e4927 100644 --- a/app/Controller/PersonController.php +++ b/app/Controller/PersonController.php @@ -1,6 +1,7 @@ driver = $driverFactory->get('default'); } - /** - * @throws \Throwable - */ public function create(PersonRequest $request, ResponseInterface $response): MessageResponseInterface { $person = $request->toPerson(); - if ($this->redis->get($person['nick'])) { + if ($this->cache->get($person['nick'])) { return $response->json(['message' => 'Esse apelido já existe'])->withStatus(422); } - $this->driver->push(new PersonJob($person)); - -// + $this->queue->push(new PersonJob($person)); - $this->redis->set($person['nick'], '.'); - $this->redis->set($person['id'], json_encode($person)); + $this->cache->set($person['nick'], '.'); + $this->cache->set($person['id'], json_encode($person)); return $response->json($person)->withStatus(201)->withHeader('Location', "/pessoas/{$person['id']}"); } public function show(RequestInterface $request, ResponseInterface $response, string $id): MessageResponseInterface { - $cached = $this->redis->get($id); - if ($cached) { - - $person = json_decode($cached); - - return $response->json($person); + if ($cached = $this->cache->get($id)) { + return $response->json(json_decode($cached)); } - $response->raw('Not found')->withStatus(404); + + return $response->raw('Not found')->withStatus(404); } public function search(RequestInterface $request, ResponseInterface $response): MessageResponseInterface @@ -85,7 +74,6 @@ public function search(RequestInterface $request, ResponseInterface $response): public function count(RequestInterface $request, ResponseInterface $response): MessageResponseInterface { - $count = Person::count(); - return $response->json(['count' => $count]); + return $response->json(['count' => Person::count()]); } } diff --git a/app/Exception/Handler/AppExceptionHandler.php b/app/Exception/Handler/AppExceptionHandler.php index 79572ec9..9db3eb42 100644 --- a/app/Exception/Handler/AppExceptionHandler.php +++ b/app/Exception/Handler/AppExceptionHandler.php @@ -1,6 +1,7 @@ params = $params; + public function __construct( + public readonly array $params + ) { } - public function handle() + public function handle(): void { Db::table('person')->insert($this->params); } diff --git a/app/Listener/DbQueryExecutedListener.php b/app/Listener/DbQueryExecutedListener.php index ba84fd08..92a8f269 100644 --- a/app/Listener/DbQueryExecutedListener.php +++ b/app/Listener/DbQueryExecutedListener.php @@ -1,6 +1,7 @@ sql; - if (! Arr::isAssoc($event->bindings)) { + if (!Arr::isAssoc($event->bindings)) { $position = 0; foreach ($event->bindings as $value) { $position = strpos($sql, '?', $position); diff --git a/app/Listener/ResumeExitCoordinatorListener.php b/app/Listener/ResumeExitCoordinatorListener.php index 59b669b2..a257a70d 100644 --- a/app/Listener/ResumeExitCoordinatorListener.php +++ b/app/Listener/ResumeExitCoordinatorListener.php @@ -1,6 +1,7 @@ 'string', 'stack' => 'array' ]; - + protected array $attributes = [ 'stack' => '[]', ]; diff --git a/app/Request/PersonRequest.php b/app/Request/PersonRequest.php index 756b2ad3..049da998 100644 --- a/app/Request/PersonRequest.php +++ b/app/Request/PersonRequest.php @@ -1,6 +1,7 @@ validated(); - + $data = $this->all(); + return [ 'id' => Uuid::uuid4()->toString(), 'nick' => $data['apelido'], diff --git a/composer.json b/composer.json index 697f5800..d74cbdaa 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "description": "Swoole e Hyperf na Rinha de Back-end.", "license": "MIT", "require": { - "php": ">=8.0", + "php": ">=8.2", "hyperf/async-queue": "^3.0", "hyperf/cache": "^3.0", "hyperf/command": "^3.0", diff --git a/config/autoload/dependencies.php b/config/autoload/dependencies.php index 55aa4211..4981b235 100644 --- a/config/autoload/dependencies.php +++ b/config/autoload/dependencies.php @@ -1,6 +1,7 @@ + fn (ContainerInterface $c) => $c->make(DriverFactory::class)->get('default') ]; diff --git a/config/routes.php b/config/routes.php index 8e9c5fcd..86a00acd 100644 --- a/config/routes.php +++ b/config/routes.php @@ -1,6 +1,7 @@ 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => '', 'nascimento' => '2023-07-01', ], @@ -82,7 +82,7 @@ public function testCreatePersonWithNullName(): void 'Content-Type' => 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => null, 'nascimento' => '2023-07-01', ], @@ -99,7 +99,7 @@ public function testCreatePersonWithEmptyBirthDate(): void 'Content-Type' => 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => 'OpenCodeCo', 'nascimento' => '', ], @@ -116,7 +116,7 @@ public function testCreatePersonWithNullBirthDate(): void 'Content-Type' => 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => 'OpenCodeCo', 'nascimento' => null, ], @@ -133,7 +133,7 @@ public function testCreatePersonWithInvalidBirthDate(): void 'Content-Type' => 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => 'OpenCodeCo', 'nascimento' => '01-07-2023', ], @@ -150,7 +150,7 @@ public function testCreatePersonWithNullStack(): void 'Content-Type' => 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => 'OpenCodeCo', 'nascimento' => '2023-07-01', ], @@ -167,7 +167,7 @@ public function testCreatePersonWithSomeStack(): void 'Content-Type' => 'application/json', ], 'json' => [ - 'apelido' => 'opencodeco', + 'apelido' => $this->randString(), 'nome' => 'OpenCodeCo', 'nascimento' => '2023-07-01', 'stack' => ['PHP', 'Swoole', 'Hyperf'], @@ -176,4 +176,9 @@ public function testCreatePersonWithSomeStack(): void assertSame(201, $response->getStatusCode(), $response->getBody()->getContents()); } + + protected function randString(): string + { + return str_pad(bin2hex(random_bytes(10)), 10); + } } diff --git a/test/HttpTestCase.php b/test/HttpTestCase.php index aa09182b..dba49de3 100644 --- a/test/HttpTestCase.php +++ b/test/HttpTestCase.php @@ -1,6 +1,7 @@ client = make(Client::class); + $this->client = \Hyperf\Support\make(Client::class); } public function __call($name, $arguments) { return $this->client->{$name}(...$arguments); } + + protected function setUp(): void + { + parent::setUp(); + Db::beginTransaction(); + } + + protected function tearDown(): void + { + Db::rollBack(); + parent::tearDown(); + } } From 87f751762882d0cff24528c92e0823f80443d0f7 Mon Sep 17 00:00:00 2001 From: Diego Borges Date: Fri, 18 Aug 2023 23:55:09 -0300 Subject: [PATCH 2/2] Update (#6) * fix: Avoid redirects without 3xx status code * chore(test): Fix make target * chore(cs): Newline at EOF * fix(dev): Redis host at Docker environment * chore(deps): Bump * Setup gatling --------- Co-authored-by: leocavalcante Co-authored-by: William Correa Co-authored-by: Diego Ferreira --- app/Controller/PersonController.php | 2 +- composer.lock | 104 +++++++++++++++++++++------- docker-compose.yml | 3 +- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/app/Controller/PersonController.php b/app/Controller/PersonController.php index 3d6e4927..7f4dc419 100644 --- a/app/Controller/PersonController.php +++ b/app/Controller/PersonController.php @@ -44,7 +44,7 @@ public function create(PersonRequest $request, ResponseInterface $response): Mes $this->cache->set($person['nick'], '.'); $this->cache->set($person['id'], json_encode($person)); - return $response->json($person)->withStatus(201)->withHeader('Location', "/pessoas/{$person['id']}"); + return $response->json($person)->withStatus(201); } public function show(RequestInterface $request, ResponseInterface $response, string $id): MessageResponseInterface diff --git a/composer.lock b/composer.lock index 96c2b297..d1cd689b 100644 --- a/composer.lock +++ b/composer.lock @@ -1093,16 +1093,16 @@ }, { "name": "hyperf/collection", - "version": "v3.0.29", + "version": "v3.0.33", "source": { "type": "git", "url": "https://github.com/hyperf/collection.git", - "reference": "c2e3f919f8c445da69e0e0c10920c6fc0754b9ad" + "reference": "0126536ab2634b6f446bcdd24ee4f4448951390b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperf/collection/zipball/c2e3f919f8c445da69e0e0c10920c6fc0754b9ad", - "reference": "c2e3f919f8c445da69e0e0c10920c6fc0754b9ad", + "url": "https://api.github.com/repos/hyperf/collection/zipball/0126536ab2634b6f446bcdd24ee4f4448951390b", + "reference": "0126536ab2634b6f446bcdd24ee4f4448951390b", "shasum": "" }, "require": { @@ -1142,7 +1142,7 @@ "pull-request": "https://github.com/hyperf/hyperf/pulls", "source": "https://github.com/hyperf/hyperf" }, - "time": "2023-07-14T03:41:52+00:00" + "time": "2023-08-18T03:42:33+00:00" }, { "name": "hyperf/command", @@ -1458,16 +1458,16 @@ }, { "name": "hyperf/coroutine", - "version": "v3.0.16", + "version": "v3.0.33", "source": { "type": "git", "url": "https://github.com/hyperf/coroutine.git", - "reference": "4944ce69d5f35407e5dbcf7e9991f1db3366f254" + "reference": "0cad1ddb1d233b02b16ebfb26d0cc5c863b0e5dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperf/coroutine/zipball/4944ce69d5f35407e5dbcf7e9991f1db3366f254", - "reference": "4944ce69d5f35407e5dbcf7e9991f1db3366f254", + "url": "https://api.github.com/repos/hyperf/coroutine/zipball/0cad1ddb1d233b02b16ebfb26d0cc5c863b0e5dd", + "reference": "0cad1ddb1d233b02b16ebfb26d0cc5c863b0e5dd", "shasum": "" }, "require": { @@ -1508,7 +1508,7 @@ "pull-request": "https://github.com/hyperf/hyperf/pulls", "source": "https://github.com/hyperf/hyperf" }, - "time": "2023-04-12T05:34:25+00:00" + "time": "2023-08-17T06:16:35+00:00" }, { "name": "hyperf/database", @@ -1632,16 +1632,16 @@ }, { "name": "hyperf/di", - "version": "v3.0.24", + "version": "v3.0.33", "source": { "type": "git", "url": "https://github.com/hyperf/di.git", - "reference": "4fa46897ffe0e1f2d1260a65a1e25dadaacbdcd2" + "reference": "bd5bf72af5f9261c2352b56d1a2ce677c1c0e304" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperf/di/zipball/4fa46897ffe0e1f2d1260a65a1e25dadaacbdcd2", - "reference": "4fa46897ffe0e1f2d1260a65a1e25dadaacbdcd2", + "url": "https://api.github.com/repos/hyperf/di/zipball/bd5bf72af5f9261c2352b56d1a2ce677c1c0e304", + "reference": "bd5bf72af5f9261c2352b56d1a2ce677c1c0e304", "shasum": "" }, "require": { @@ -1693,7 +1693,7 @@ "pull-request": "https://github.com/hyperf/hyperf/pulls", "source": "https://github.com/hyperf/hyperf" }, - "time": "2023-06-05T07:53:17+00:00" + "time": "2023-08-15T07:08:10+00:00" }, { "name": "hyperf/dispatcher", @@ -3101,16 +3101,16 @@ }, { "name": "hyperf/validation", - "version": "v3.0.28", + "version": "v3.0.33", "source": { "type": "git", "url": "https://github.com/hyperf/validation.git", - "reference": "c1aa358eabf24148487602005e49565bbf02979b" + "reference": "a35fe9b755942a803331bdc79547642caabc7e05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperf/validation/zipball/c1aa358eabf24148487602005e49565bbf02979b", - "reference": "c1aa358eabf24148487602005e49565bbf02979b", + "url": "https://api.github.com/repos/hyperf/validation/zipball/a35fe9b755942a803331bdc79547642caabc7e05", + "reference": "a35fe9b755942a803331bdc79547642caabc7e05", "shasum": "" }, "require": { @@ -3157,9 +3157,9 @@ ], "support": { "issues": "https://github.com/hyperf/validation/issues", - "source": "https://github.com/hyperf/validation/tree/v3.0.28" + "source": "https://github.com/hyperf/validation/tree/v3.0.33" }, - "time": "2023-07-03T04:37:00+00:00" + "time": "2023-08-10T07:43:04+00:00" }, { "name": "laminas/laminas-mime", @@ -3384,25 +3384,29 @@ }, { "name": "nesbot/carbon", - "version": "2.68.1", + "version": "2.69.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da" + "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4f991ed2a403c85efbc4f23eb4030063fdbe01da", - "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c", + "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.1.8 || ^8.0", + "psr/clock": "^1.0", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php80": "^1.16", "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" }, + "provide": { + "psr/clock-implementation": "1.0" + }, "require-dev": { "doctrine/dbal": "^2.0 || ^3.1.4", "doctrine/orm": "^2.7", @@ -3482,7 +3486,7 @@ "type": "tidelift" } ], - "time": "2023-06-20T18:29:04+00:00" + "time": "2023-08-03T09:00:52+00:00" }, { "name": "nikic/fast-route", @@ -3707,6 +3711,54 @@ ], "time": "2023-02-25T19:38:58+00:00" }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, { "name": "psr/container", "version": "2.0.2", diff --git a/docker-compose.yml b/docker-compose.yml index a4cfcd29..8d8bbd6d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: APP_STAGE: dev environment: DB_HOST: db + REDIS_HOST: cache volumes: - ./:/opt/www depends_on: @@ -71,4 +72,4 @@ services: networks: default: - name: rinha-de-backend \ No newline at end of file + name: rinha-de-backend