Browse Source

Adding withSessions parallel processing for Queries and Updates (#5236)

vka 5 years ago
parent
commit
f21c9cf4e7

+ 5 - 23
frameworks/PHP/hamlet/Benchmark/Application.php

@@ -4,13 +4,12 @@ namespace Benchmark;
 
 use Benchmark\Resources\{DbResource, FortuneResource, HelloJsonResource, HelloTextResource, QueriesResource, UpdateResource};
 use Cache\Adapter\PHPArray\ArrayCachePool;
-use Hamlet\Database\{Database, Session};
+use Hamlet\Database\Database;
 use Hamlet\Http\Applications\AbstractApplication;
 use Hamlet\Http\Requests\Request;
 use Hamlet\Http\Resources\{HttpResource, NotFoundResource};
 use Hamlet\Http\Responses\{Response, ServerErrorResponse};
 use Psr\Cache\CacheItemPoolInterface;
-use Throwable;
 
 class Application extends AbstractApplication
 {
@@ -26,15 +25,6 @@ class Application extends AbstractApplication
         $this->database = $database;
     }
 
-    public function run(Request $request): Response
-    {
-        try {
-            return parent::run($request);
-        } catch (Throwable $e) {
-            return new ServerErrorResponse;
-        }
-    }
-
     public function findResource(Request $request): HttpResource
     {
         switch ($request->getPath()) {
@@ -43,21 +33,13 @@ class Application extends AbstractApplication
             case '/json':
                 return new HelloJsonResource;
             case '/db':
-                return $this->database->withSession(function (Session $session) {
-                    return new DbResource($session);
-                });
+                return new DbResource($this->database);
             case '/queries':
-                return $this->database->withSession(function (Session $session) {
-                    return new QueriesResource($session);
-                });
+                return new QueriesResource($this->database);
             case '/fortunes':
-                return $this->database->withSession(function (Session $session) {
-                    return new FortuneResource($session);
-                });
+                return new FortuneResource($this->database);
             case '/update':
-                return $this->database->withSession(function (Session $session) {
-                    return new UpdateResource($session);
-                });
+                return new UpdateResource($this->database);
         }
         return new NotFoundResource;
     }

+ 19 - 14
frameworks/PHP/hamlet/Benchmark/Resources/DbResource.php

@@ -3,7 +3,7 @@
 namespace Benchmark\Resources;
 
 use Benchmark\Entities\RandomNumber;
-use Hamlet\Database\{Procedure, Session};
+use Hamlet\Database\{Database, Session};
 use Hamlet\Http\Entities\JsonEntity;
 use Hamlet\Http\Requests\Request;
 use Hamlet\Http\Resources\HttpResource;
@@ -11,26 +11,31 @@ use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
 class DbResource implements HttpResource
 {
-    /** @var Procedure */
-    private $procedure;
+    /** @var Database */
+    protected $database;
 
-    public function __construct(Session $session)
+    public function __construct(Database $database)
     {
-        $this->procedure = $session->prepare('
-            SELECT id,
-                   randomNumber 
-              FROM World 
-             WHERE id = ?
-        ');
+        $this->database = $database;
     }
 
     public function getResponse(Request $request): Response
     {
         $id = mt_rand(1, 10000);
-        $this->procedure->bindInteger($id);
-        $record = $this->procedure->processOne()
-            ->selectAll()->cast(RandomNumber::class)
-            ->collectHead();
+        $record = $this->database->withSession(
+            function (Session $session) use ($id) {
+                $procedure = $session->prepare('
+                    SELECT id,
+                           randomNumber 
+                      FROM World 
+                     WHERE id = ?
+                ');
+                $procedure->bindInteger($id);
+                return $procedure->processOne()
+                    ->selectAll()->cast(RandomNumber::class)
+                    ->collectHead();
+            }
+        );
         return new SimpleOKResponse(new JsonEntity($record));
     }
 }

+ 14 - 19
frameworks/PHP/hamlet/Benchmark/Resources/FortuneResource.php

@@ -4,32 +4,27 @@ namespace Benchmark\Resources;
 
 use Benchmark\Entities\FortuneEntity;
 use Benchmark\Entities\Message;
-use Hamlet\Database\{Procedure, Session};
+use Hamlet\Database\Session;
 use Hamlet\Http\Requests\Request;
 use Hamlet\Http\Resources\HttpResource;
 use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
-class FortuneResource implements HttpResource
+class FortuneResource extends DbResource
 {
-    /** @var Procedure */
-    private $procedure;
-
-    public function __construct(Session $session)
-    {
-        $query = '
-            SELECT id,
-                   message
-              FROM Fortune
-        ';
-        $this->procedure = $session->prepare($query);
-    }
-
     public function getResponse(Request $request): Response
     {
-        $messages = $this->procedure->processAll()
-            ->selectAll()->cast(Message::class)
-            ->collectAll();
-
+        $messages = $this->database->withSession(
+            function (Session $session) {
+                $procedure = $session->prepare('
+                    SELECT id,
+                           message
+                      FROM Fortune
+                ');
+                return $procedure->processAll()
+                    ->selectAll()->cast(Message::class)
+                    ->collectAll();
+            }
+        );
         $messages[] = new Message(0, 'Additional fortune added at request time.');
         usort($messages, function (Message $a, Message $b): int {
             return $a->message() <=> $b->message();

+ 17 - 23
frameworks/PHP/hamlet/Benchmark/Resources/QueriesResource.php

@@ -3,42 +3,36 @@
 namespace Benchmark\Resources;
 
 use Benchmark\Entities\RandomNumber;
-use Hamlet\Database\{Procedure, Session};
+use Hamlet\Database\Session;
 use Hamlet\Http\Entities\JsonEntity;
 use Hamlet\Http\Requests\Request;
 use Hamlet\Http\Resources\HttpResource;
 use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
-class QueriesResource implements HttpResource
+class QueriesResource extends DbResource
 {
     use QueriesCountTrait;
 
-    /** @var Procedure */
-    private $procedure;
-
-    public function __construct(Session $session)
-    {
-        $this->procedure = $session->prepare('
-            SELECT id,
-                   randomNumber 
-              FROM World 
-             WHERE id = ?
-        ');
-    }
-
     public function getResponse(Request $request): Response
     {
         $count = $this->getQueriesCount($request);
-
-        $payload = [];
+        $callables = [];
         while ($count--) {
-            $id = mt_rand(1, 10000);
-            $this->procedure->bindInteger($id);
-            $payload[] = $this->procedure->processOne()
-                ->selectAll()->cast(RandomNumber::class)
-                ->collectHead();
+            $callables[] = function (Session $session) {
+                $id = mt_rand(1, 10000);
+                $procedure = $session->prepare('
+                    SELECT id,
+                           randomNumber 
+                      FROM World 
+                     WHERE id = ?
+                ');
+                $procedure->bindInteger($id);
+                return $procedure->processOne()
+                    ->selectAll()->cast(RandomNumber::class)
+                    ->collectHead();
+            };
         }
-
+        $payload = $this->database->withSessions($callables);
         return new SimpleOKResponse(new JsonEntity($payload));
     }
 }

+ 32 - 41
frameworks/PHP/hamlet/Benchmark/Resources/UpdateResource.php

@@ -3,60 +3,51 @@
 namespace Benchmark\Resources;
 
 use Benchmark\Entities\RandomNumber;
-use Hamlet\Database\{Procedure, Session};
+use Hamlet\Database\Session;
 use Hamlet\Http\Entities\JsonEntity;
 use Hamlet\Http\Requests\Request;
 use Hamlet\Http\Resources\HttpResource;
 use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
-class UpdateResource implements HttpResource
+class UpdateResource extends DbResource
 {
     use QueriesCountTrait;
 
-    /** @var Procedure */
-    private $selectProcedure;
-
-    /** @var Procedure */
-    private $updateProcedure;
-
-    public function __construct(Session $session)
-    {
-        $this->selectProcedure = $session->prepare('
-            SELECT id,
-                   randomNumber 
-              FROM World
-             WHERE id = ?
-        ');
-        $this->updateProcedure = $session->prepare('
-            UPDATE World
-               SET randomNumber = ? 
-             WHERE id = ?
-        ');
-    }
-
     public function getResponse(Request $request): Response
     {
         $count = $this->getQueriesCount($request);
-
-        $payload = [];
+        $callables = [];
         while ($count--) {
-            $id = mt_rand(1, 10000);
-            $randomNumber = mt_rand(1, 10000);
-
-            $this->selectProcedure->bindInteger($id);
-            /** @var RandomNumber $entry */
-            $entry = $this->selectProcedure->processOne()
-                ->selectAll()->cast(RandomNumber::class)
-                ->collectHead();
-            $modifiedEntry = $entry->withNumber($randomNumber);
-
-            $this->updateProcedure->bindInteger($modifiedEntry->number());
-            $this->updateProcedure->bindInteger($modifiedEntry->id());
-            $this->updateProcedure->execute();
-
-            $payload[] = $modifiedEntry;
+            $callables[] = function (Session $session) {
+                $id = mt_rand(1, 10000);
+                $randomNumber = mt_rand(1, 10000);
+
+                $selectProcedure = $session->prepare('
+                    SELECT id,
+                           randomNumber 
+                      FROM World
+                     WHERE id = ?
+                ');
+                $selectProcedure->bindInteger($id);
+                /** @var RandomNumber $entry */
+                $entry = $selectProcedure->processOne()
+                    ->selectAll()->cast(RandomNumber::class)
+                    ->collectHead();
+                $modifiedEntry = $entry->withNumber($randomNumber);
+
+                $updateProcedure = $session->prepare('
+                    UPDATE World
+                       SET randomNumber = ? 
+                     WHERE id = ?
+                ');
+                $updateProcedure->bindInteger($modifiedEntry->number());
+                $updateProcedure->bindInteger($modifiedEntry->id());
+                $updateProcedure->execute();
+
+                return $modifiedEntry;
+            };
         }
-
+        $payload = $this->database->withSessions($callables);
         return new SimpleOKResponse(new JsonEntity($payload));
     }
 }