Преглед изворни кода

PHP 8 support (#6732)

* PHP 8 support,
Swoole / workerman fixes
Refactoring
Adding cached query endpoints
Replaced MySQLi with PDO

* Repositories added

* Few more files missing

* Adding parallel
vka пре 4 година
родитељ
комит
ab93bbf484
27 измењених фајлова са 233 додато и 192 уклоњено
  1. 0 2
      frameworks/PHP/hamlet/.gitignore
  2. 8 14
      frameworks/PHP/hamlet/Benchmark/Application.php
  3. 1 6
      frameworks/PHP/hamlet/Benchmark/Entities/FortuneEntity.php
  4. 2 12
      frameworks/PHP/hamlet/Benchmark/Entities/Message.php
  5. 4 14
      frameworks/PHP/hamlet/Benchmark/Entities/RandomNumber.php
  6. 21 0
      frameworks/PHP/hamlet/Benchmark/Repositories/FortuneRepository.php
  7. 34 0
      frameworks/PHP/hamlet/Benchmark/Repositories/WorldRepository.php
  8. 30 0
      frameworks/PHP/hamlet/Benchmark/Resources/CachedQueriesResource.php
  9. 5 23
      frameworks/PHP/hamlet/Benchmark/Resources/DbResource.php
  10. 3 14
      frameworks/PHP/hamlet/Benchmark/Resources/FortuneResource.php
  11. 6 20
      frameworks/PHP/hamlet/Benchmark/Resources/QueriesResource.php
  12. 15 36
      frameworks/PHP/hamlet/Benchmark/Resources/UpdateResource.php
  13. 1 5
      frameworks/PHP/hamlet/README.md
  14. 6 3
      frameworks/PHP/hamlet/benchmark_config.json
  15. 18 0
      frameworks/PHP/hamlet/composer-swoole.json
  16. 18 0
      frameworks/PHP/hamlet/composer-workerman.json
  17. 4 4
      frameworks/PHP/hamlet/composer.json
  18. 1 0
      frameworks/PHP/hamlet/config.toml
  19. 4 4
      frameworks/PHP/hamlet/deploy/fpm/nginx.conf
  20. 2 2
      frameworks/PHP/hamlet/deploy/fpm/php-fpm.conf
  21. 7 0
      frameworks/PHP/hamlet/deploy/fpm/php.ini
  22. 2 6
      frameworks/PHP/hamlet/hamlet-swoole.dockerfile
  23. 22 12
      frameworks/PHP/hamlet/hamlet-workerman.dockerfile
  24. 10 8
      frameworks/PHP/hamlet/hamlet.dockerfile
  25. 4 5
      frameworks/PHP/hamlet/index.php
  26. 2 1
      frameworks/PHP/hamlet/swoole.php
  27. 3 1
      frameworks/PHP/hamlet/workerman.php

+ 0 - 2
frameworks/PHP/hamlet/.gitignore

@@ -1,4 +1,2 @@
-obj/
-bin/
 vendor/
 composer.lock

+ 8 - 14
frameworks/PHP/hamlet/Benchmark/Application.php

@@ -2,28 +2,17 @@
 
 namespace Benchmark;
 
-use Benchmark\Resources\{DbResource, FortuneResource, HelloJsonResource, HelloTextResource, QueriesResource, UpdateResource};
-use Cache\Adapter\PHPArray\ArrayCachePool;
+use Benchmark\Resources\{CachedQueriesResource, DbResource, FortuneResource, HelloJsonResource, HelloTextResource, QueriesResource, UpdateResource};
+use Cache\Adapter\Apcu\ApcuCachePool;
 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;
 
 class Application extends AbstractApplication
 {
-    /** @var CacheItemPoolInterface */
-    private $cache;
-
-    /** @var Database */
-    private $database;
-
-    public function __construct(Database $database)
-    {
-        $this->cache = new ArrayCachePool;
-        $this->database = $database;
-    }
+    public function __construct(private Database $database, private CacheItemPoolInterface|null $cache = null) {}
 
     public function findResource(Request $request): HttpResource
     {
@@ -36,6 +25,8 @@ class Application extends AbstractApplication
                 return new DbResource($this->database);
             case '/queries':
                 return new QueriesResource($this->database);
+            case '/cached-worlds':
+                return new CachedQueriesResource($this->getCache($request), $this->database);
             case '/fortunes':
                 return new FortuneResource($this->database);
             case '/update':
@@ -46,6 +37,9 @@ class Application extends AbstractApplication
 
     protected function getCache(Request $request): CacheItemPoolInterface
     {
+        if (!$this->cache) {
+            $this->cache = new ApcuCachePool;
+        }
         return $this->cache;
     }
 }

+ 1 - 6
frameworks/PHP/hamlet/Benchmark/Entities/FortuneEntity.php

@@ -6,12 +6,7 @@ use Hamlet\Http\Entities\AbstractMustacheEntity;
 
 class FortuneEntity extends AbstractMustacheEntity
 {
-    private $messages;
-
-    public function __construct(array $messages)
-    {
-        $this->messages = $messages;
-    }
+    public function __construct(private array $messages) {}
 
     protected function getTemplateData()
     {

+ 2 - 12
frameworks/PHP/hamlet/Benchmark/Entities/Message.php

@@ -7,17 +7,7 @@ use JsonSerializable;
 
 class Message implements Entity, JsonSerializable
 {
-    /** @var int */
-    private $id;
-
-    /** @var string */
-    private $message;
-
-    public function __construct(int $id, string $message)
-    {
-        $this->id = $id;
-        $this->message = $message;
-    }
+    public function __construct(private int $id, private string $message) {}
 
     public function id(): int
     {
@@ -29,7 +19,7 @@ class Message implements Entity, JsonSerializable
         return $this->message;
     }
 
-    public function jsonSerialize()
+    public function jsonSerialize(): array
     {
         return [
             'id' => $this->id,

+ 4 - 14
frameworks/PHP/hamlet/Benchmark/Entities/RandomNumber.php

@@ -5,19 +5,9 @@ namespace Benchmark\Entities;
 use Hamlet\Database\Entity;
 use JsonSerializable;
 
-class RandomNumber implements Entity, JsonSerializable
+final class RandomNumber implements Entity, JsonSerializable
 {
-    /** @var int */
-    private $id;
-
-    /** @var int */
-    private $randomNumber;
-
-    public function __construct(int $id, int $randomNumber)
-    {
-        $this->id = $id;
-        $this->randomNumber = $randomNumber;
-    }
+    public function __construct(private int $id, private int $randomNumber) {}
 
     public function id(): int
     {
@@ -29,12 +19,12 @@ class RandomNumber implements Entity, JsonSerializable
         return $this->randomNumber;
     }
 
-    public function withNumber(int $number): RandomNumber
+    public function withNumber(int $number): self
     {
         return new self($this->id, $number);
     }
 
-    public function jsonSerialize()
+    public function jsonSerialize(): array
     {
         return [
             'id' => $this->id,

+ 21 - 0
frameworks/PHP/hamlet/Benchmark/Repositories/FortuneRepository.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Benchmark\Repositories;
+
+use Benchmark\Entities\Message;
+use Hamlet\Database\Session;
+
+class FortuneRepository
+{
+    /**
+     * @return callable(Session):array<Message>
+     */
+    public function findAll(): callable
+    {
+        return fn (Session $session) =>
+            $session->prepare('SELECT id, message FROM Fortune')
+                ->processAll()
+                ->selectAll()->cast(Message::class)
+                ->collectAll();
+    }
+}

+ 34 - 0
frameworks/PHP/hamlet/Benchmark/Repositories/WorldRepository.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace Benchmark\Repositories;
+
+use Benchmark\Entities\RandomNumber;
+use Hamlet\Database\Session;
+
+class WorldRepository
+{
+    /**
+     * @return callable(Session):?RandomNumber
+     */
+    public function findById(int $id): callable
+    {
+        return fn (Session $session) =>
+            $session->prepare('SELECT id, randomNumber FROM World WHERE id = ?')
+                ->bindInteger($id)
+                ->processOne()
+                ->selectAll()->cast(RandomNumber::class)
+                ->collectHead();
+    }
+
+    /**
+     * @return callable(Session):void
+     */
+    public function updateNumber(RandomNumber $number): callable
+    {
+        return fn (Session $session) =>
+            $session->prepare('UPDATE World SET randomNumber = ? WHERE id = ?')
+                ->bindInteger($number->number())
+                ->bindInteger($number->id())
+                ->execute();
+    }
+}

+ 30 - 0
frameworks/PHP/hamlet/Benchmark/Resources/CachedQueriesResource.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace Benchmark\Resources;
+
+use Cache\Adapter\Common\CacheItem;
+use Hamlet\Database\Database;
+use Hamlet\Http\Requests\Request;
+use Hamlet\Http\Responses\Response;
+use Psr\Cache\CacheItemPoolInterface;
+
+class CachedQueriesResource extends QueriesResource
+{
+    public function __construct(private CacheItemPoolInterface $cache, Database $database)
+    {
+        parent::__construct($database);
+    }
+
+    public function getResponse(Request $request): Response
+    {
+        $count = $this->getQueriesCount($request);
+        $key = 'count.' . $count;
+        $item = $this->cache->getItem($key);
+        if ($item->isHit()) {
+            return $item->get();
+        }
+        $response = parent::getResponse($request);
+        $this->cache->save(new CacheItem($key, true, $response));
+        return $response;
+    }
+}

+ 5 - 23
frameworks/PHP/hamlet/Benchmark/Resources/DbResource.php

@@ -2,8 +2,8 @@
 
 namespace Benchmark\Resources;
 
-use Benchmark\Entities\RandomNumber;
-use Hamlet\Database\{Database, Session};
+use Benchmark\Repositories\WorldRepository;
+use Hamlet\Database\{Database};
 use Hamlet\Http\Entities\JsonEntity;
 use Hamlet\Http\Requests\Request;
 use Hamlet\Http\Resources\HttpResource;
@@ -11,31 +11,13 @@ use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
 class DbResource implements HttpResource
 {
-    /** @var Database */
-    protected $database;
-
-    public function __construct(Database $database)
-    {
-        $this->database = $database;
-    }
+    public function __construct(protected Database $database) {}
 
     public function getResponse(Request $request): Response
     {
+        $repository = new WorldRepository;
         $id = mt_rand(1, 10000);
-        $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();
-            }
-        );
+        $record = $this->database->withSession($repository->findById($id));
         return new SimpleOKResponse(new JsonEntity($record));
     }
 }

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

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

+ 6 - 20
frameworks/PHP/hamlet/Benchmark/Resources/QueriesResource.php

@@ -2,11 +2,9 @@
 
 namespace Benchmark\Resources;
 
-use Benchmark\Entities\RandomNumber;
-use Hamlet\Database\Session;
+use Benchmark\Repositories\WorldRepository;
 use Hamlet\Http\Entities\JsonEntity;
 use Hamlet\Http\Requests\Request;
-use Hamlet\Http\Resources\HttpResource;
 use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
 class QueriesResource extends DbResource
@@ -15,24 +13,12 @@ class QueriesResource extends DbResource
 
     public function getResponse(Request $request): Response
     {
+        $repository = new WorldRepository;
         $count = $this->getQueriesCount($request);
-        $callables = [];
-        while ($count--) {
-            $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);
+        $payload = $this->database->withSessions(array_map(
+            fn () => $repository->findById(mt_rand(1, 10000)),
+            range(1, $count)
+        ));
         return new SimpleOKResponse(new JsonEntity($payload));
     }
 }

+ 15 - 36
frameworks/PHP/hamlet/Benchmark/Resources/UpdateResource.php

@@ -2,11 +2,9 @@
 
 namespace Benchmark\Resources;
 
-use Benchmark\Entities\RandomNumber;
-use Hamlet\Database\Session;
+use Benchmark\Repositories\WorldRepository;
 use Hamlet\Http\Entities\JsonEntity;
 use Hamlet\Http\Requests\Request;
-use Hamlet\Http\Resources\HttpResource;
 use Hamlet\Http\Responses\{Response, SimpleOKResponse};
 
 class UpdateResource extends DbResource
@@ -15,39 +13,20 @@ class UpdateResource extends DbResource
 
     public function getResponse(Request $request): Response
     {
+        $repository = new WorldRepository;
         $count = $this->getQueriesCount($request);
-        $callables = [];
-        while ($count--) {
-            $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));
+        $entries = $this->database->withSessions(array_map(
+            fn () => $repository->findById(mt_rand(1, 10000)),
+            range(1, $count),
+        ));
+        $modifiedEntries = array_map(
+            fn ($entry) => $entry->withNumber(mt_rand(1, 10000)),
+            $entries
+        );
+        $this->database->withSessions(array_map(
+            fn ($modifiedEntry) => $repository->updateNumber($modifiedEntry),
+            $modifiedEntries
+        ));
+        return new SimpleOKResponse(new JsonEntity($modifiedEntries));
     }
 }

+ 1 - 5
frameworks/PHP/hamlet/README.md

@@ -6,8 +6,4 @@ Current submission tests the following configurations:
 
 - Hamlet
 - Hamlet + Swoole
-
-## (Some) Documentation
-
-- [Short overview of framework's architecture](https://notes.kartashov.com/2016/07/08/simple-caching-web-framework/)
-- [Data processor](https://notes.kartashov.com/2017/05/09/result-set-processor/)
+- Hamlet + Workerman

+ 6 - 3
frameworks/PHP/hamlet/benchmark_config.json

@@ -6,6 +6,7 @@
       "json_url": "/json",
       "db_url": "/db",
       "query_url": "/queries?queries=",
+      "cached_query_url": "/cached-worlds?queries=",
       "fortune_url": "/fortunes",
       "update_url": "/update?queries=",
       "port": 8080,
@@ -14,7 +15,7 @@
       "database": "mysql",
       "framework": "hamlet",
       "language": "PHP",
-      "flavor": "PHP7",
+      "flavor": "PHP8",
       "orm": "micro",
       "platform": "FPM/FastCGI",
       "webserver": "nginx",
@@ -29,6 +30,7 @@
       "json_url": "/json",
       "db_url": "/db",
       "query_url": "/queries?queries=",
+      "cached_query_url": "/cached-worlds?queries=",
       "fortune_url": "/fortunes",
       "update_url": "/update?queries=",
       "port": 8080,
@@ -37,7 +39,7 @@
       "database": "mysql",
       "framework": "hamlet",
       "language": "PHP",
-      "flavor": "PHP7",
+      "flavor": "PHP8",
       "orm": "micro",
       "platform": "swoole",
       "webserver": "none",
@@ -52,6 +54,7 @@
       "json_url": "/json",
       "db_url": "/db",
       "query_url": "/queries?queries=",
+      "cached_query_url": "/cached-worlds?queries=",
       "fortune_url": "/fortunes",
       "update_url": "/update?queries=",
       "port": 8080,
@@ -60,7 +63,7 @@
       "database": "mysql",
       "framework": "hamlet",
       "language": "PHP",
-      "flavor": "PHP7",
+      "flavor": "PHP8",
       "orm": "micro",
       "platform": "workerman",
       "webserver": "none",

+ 18 - 0
frameworks/PHP/hamlet/composer-swoole.json

@@ -0,0 +1,18 @@
+{
+  "config": {
+    "optimize-autoloader": true,
+    "classmap-authoritative": true
+  },
+  "require": {
+    "php": "^8",
+    "hamlet-framework/http" : "@stable",
+    "hamlet-framework/http-swoole": "@stable",
+    "hamlet-framework/db-mysql-swoole": "@stable",
+    "cache/array-adapter": "@stable"
+  },
+  "autoload": {
+    "psr-4": {
+      "Benchmark\\": "Benchmark/"
+    }
+  }
+}

+ 18 - 0
frameworks/PHP/hamlet/composer-workerman.json

@@ -0,0 +1,18 @@
+{
+  "config": {
+    "optimize-autoloader": true,
+    "classmap-authoritative": true
+  },
+  "require": {
+    "php": "^8",
+    "hamlet-framework/http" : "@stable",
+    "hamlet-framework/http-workerman": "@stable",
+    "hamlet-framework/db-pdo": "@stable",
+    "cache/array-adapter": "@stable"
+  },
+  "autoload": {
+    "psr-4": {
+      "Benchmark\\": "Benchmark/"
+    }
+  }
+}

+ 4 - 4
frameworks/PHP/hamlet/composer.json

@@ -1,13 +1,13 @@
 {
-  "minimum-stability": "dev",
   "config": {
     "optimize-autoloader": true,
     "classmap-authoritative": true
   },
   "require": {
-    "hamlet-framework/http" : "dev-master",
-    "hamlet-framework/db-mysql": "dev-master",
-    "cache/array-adapter": "^1"
+    "php": "^8",
+    "hamlet-framework/http" : "@stable",
+    "hamlet-framework/db-pdo": "@stable",
+    "cache/apcu-adapter": "@stable"
   },
   "autoload": {
     "psr-4": {

+ 1 - 0
frameworks/PHP/hamlet/config.toml

@@ -6,6 +6,7 @@ urls.plaintext = "/plaintext"
 urls.json = "/json"
 urls.db = "/db"
 urls.query = "/queries?queries="
+urls.cached_query = "/cached-worlds?queries="
 urls.update = "/update?queries="
 urls.fortune = "/fortunes"
 approach = "Realistic"

+ 4 - 4
frameworks/PHP/hamlet/deploy/fpm/nginx.conf

@@ -27,16 +27,16 @@ http {
 
     fastcgi_buffers 256 16k;
     fastcgi_buffer_size 128k;
-    fastcgi_connect_timeout 30s;
-    fastcgi_send_timeout 60s;
-    fastcgi_read_timeout 60s;
+    fastcgi_connect_timeout 120s;
+    fastcgi_send_timeout 120s;
+    fastcgi_read_timeout 120s;
     fastcgi_busy_buffers_size 256k;
     fastcgi_temp_file_write_size 256k;
     reset_timedout_connection on;
     server_names_hash_bucket_size 100;
 
     upstream fastcgi_backend {
-        server unix:/var/run/php7.3-fpm.sock;
+        server unix:/var/run/php-fpm.sock;
         keepalive 40;
     }
 

+ 2 - 2
frameworks/PHP/hamlet/deploy/fpm/php-fpm.conf

@@ -1,12 +1,12 @@
 [global]
-pid = /var/run/php7.3-fpm.pid
+pid = /var/run/php-fpm.pid
 error_log = /dev/stderr
 systemd_interval = 0
 
 [www]
 user = www-data
 group = www-data
-listen = /var/run/php7.3-fpm.sock
+listen = /var/run/php-fpm.sock
 listen.backlog = 65535
 listen.owner = www-data
 listen.group = www-data

+ 7 - 0
frameworks/PHP/hamlet/deploy/fpm/php.ini

@@ -9,6 +9,13 @@ opcache.enable_cli=1
 opcache.optimization_level = 0xFFFFFFFF
 opcache.huge_code_pages = 0
 opcache.validate_timestamps = 0
+opcache.jit_buffer_size = 128M
+opcache.jit = 1255
 
 realpath_cache_ttl = 1200
 memory_limit = 512M
+
+display_errors = 0
+error_reporting = E_ALL
+zend.assertions = 0
+assert.exception = 0

+ 2 - 6
frameworks/PHP/hamlet/hamlet-swoole.dockerfile

@@ -1,4 +1,4 @@
-FROM php:7.4
+FROM php:8.0
 
 RUN pecl install swoole > /dev/null && \
     docker-php-ext-enable swoole
@@ -6,9 +6,6 @@ RUN pecl install swoole > /dev/null && \
 RUN docker-php-ext-install mysqli > /dev/null && \
     docker-php-ext-enable mysqli
 
-RUN docker-php-ext-install pdo_mysql > /dev/null && \
-    docker-php-ext-enable pdo_mysql
-
 RUN apt-get update -yqq && \
     apt-get install -yqq git unzip
 
@@ -16,10 +13,9 @@ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local
 
 ADD ./ /php
 WORKDIR /php
+COPY ./composer-swoole.json composer.json
 RUN chmod -R 777 /php
 
-RUN composer require hamlet-framework/http-swoole:dev-master --quiet
-RUN composer require hamlet-framework/db-mysql-swoole:dev-master --quiet
 RUN composer update --no-dev --quiet
 
 EXPOSE 8080

+ 22 - 12
frameworks/PHP/hamlet/hamlet-workerman.dockerfile

@@ -1,24 +1,34 @@
-FROM ubuntu:20.04
+FROM php:8.0-zts
 
-ARG DEBIAN_FRONTEND=noninteractive
+ENV PHP_VERSION 8.0
+ENV PARALLEL_VERSION 360c667b7632a639a983f17c5d97b92cbe4f7c95
 
-RUN apt-get update -yqq && apt-get install -yqq software-properties-common > /dev/null
-RUN LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
-RUN apt-get update -yqq > /dev/null && \
-    apt-get install -yqq php7.4 php7.4-common php7.4-cli php7.4-mysql  > /dev/null
+RUN docker-php-ext-install pdo_mysql > /dev/null && docker-php-ext-enable pdo_mysql
+RUN docker-php-ext-install sockets   > /dev/null && docker-php-ext-enable sockets
+RUN docker-php-ext-install pcntl     > /dev/null && docker-php-ext-enable pcntl
 
-RUN apt-get install -yqq composer > /dev/null
+RUN apt-get update -yqq > /dev/null \
+    && apt-get install -yqq git unzip libevent-dev libssl-dev > /dev/null
 
-RUN apt-get install -y php-pear php-dev libevent-dev > /dev/null
-RUN printf "\n\n /usr/lib/x86_64-linux-gnu/\n\n\nno\n\n\n" | pecl install event > /dev/null && echo "extension=event.so" > /etc/php/7.4/cli/conf.d/event.ini
+RUN git clone https://github.com/krakjoe/parallel \
+    && cd parallel \
+    && git checkout 360c667b7632a639a983f17c5d97b92cbe4f7c95 \
+    && phpize > /dev/null \
+    && ./configure --enable-parallel > /dev/null \
+    && make > /dev/null \
+    && make install > /dev/null
 
-COPY deploy/fpm/php.ini /etc/php/7.4/fpm/php.ini
+RUN pecl install event-3.0.4 > /dev/null \
+    && echo "extension=event.so" > /usr/local/etc/php/conf.d/event.ini
+
+COPY deploy/fpm/php.ini /usr/local/etc/php/conf.d/hamlet.ini
+
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
 
 ADD ./ /hamlet
 WORKDIR /hamlet
+COPY ./composer-workerman.json composer.json
 
-RUN composer require hamlet-framework/http-workerman:dev-master --quiet
-RUN composer require hamlet-framework/db-pdo:dev-master --quiet
 RUN composer update --no-dev --quiet
 
 EXPOSE 8080

+ 10 - 8
frameworks/PHP/hamlet/hamlet.dockerfile

@@ -1,25 +1,27 @@
-FROM ubuntu:20.04
+FROM ubuntu:20.10
 
+ENV PHP_VERSION 8.0
 ARG DEBIAN_FRONTEND=noninteractive
 
 RUN apt-get update -yqq && apt-get install -yqq software-properties-common > /dev/null
 RUN LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
 RUN apt-get update -yqq > /dev/null && \
-    apt-get install -yqq nginx git unzip php7.4 php7.4-common php7.4-cli php7.4-fpm php7.4-mysql  > /dev/null
+    apt-get install -yqq nginx git unzip curl \
+    php${PHP_VERSION}-cli php${PHP_VERSION}-fpm php${PHP_VERSION}-apcu php${PHP_VERSION}-pdo-mysql > /dev/null
 
 RUN apt-get install -yqq composer > /dev/null
 
-COPY deploy/fpm/php-fpm.conf /etc/php/7.4/fpm/php-fpm.conf
-COPY deploy/fpm/php.ini /etc/php/7.4/fpm/php.ini
-
 ADD ./ /app
 WORKDIR /app
 
-RUN if [ $(nproc) = 2 ]; then sed -i "s|pm.max_children = 1024|pm.max_children = 512|g" /etc/php/7.4/fpm/php-fpm.conf ; fi;
-
 RUN composer update --no-dev --quiet
 
+COPY deploy/fpm/php-fpm.conf /etc/php/${PHP_VERSION}/fpm/php-fpm.conf
+COPY deploy/fpm/php.ini /etc/php/${PHP_VERSION}/fpm/php.ini
+
+RUN if [ $(nproc) = 2 ]; then sed -i "s|pm.max_children = 1024|pm.max_children = 512|g" /etc/php/${PHP_VERSION}/fpm/php-fpm.conf ; fi;
+
 EXPOSE 8080
 
-CMD service php7.4-fpm start \
+CMD service php${PHP_VERSION}-fpm start \
     && nginx -c /app/deploy/fpm/nginx.conf -g "daemon off;"

+ 4 - 5
frameworks/PHP/hamlet/index.php

@@ -1,16 +1,15 @@
 <?php
 
 use Benchmark\Application;
-use Hamlet\Database\MySQL\MySQLDatabase;
+use Hamlet\Database\PDO\PDODatabase;
 use Hamlet\Http\Bootstraps\ServerBootstrap;
 
 require_once __DIR__ . '/vendor/autoload.php';
 
-$database = new MySQLDatabase(
-    'p:tfb-database',
+$database = new PDODatabase(
+    'mysql:host=tfb-database;dbname=hello_world',
     'benchmarkdbuser',
-    'benchmarkdbpass',
-    'hello_world'
+    'benchmarkdbpass'
 );
 $application = new Application($database);
 ServerBootstrap::run($application);

+ 2 - 1
frameworks/PHP/hamlet/swoole.php

@@ -1,6 +1,7 @@
 <?php
 
 use Benchmark\Application;
+use Cache\Adapter\PHPArray\ArrayCachePool;
 use Hamlet\Database\MySQLSwoole\MySQLSwooleDatabase;
 use Hamlet\Http\Swoole\Bootstraps\SwooleBootstrap;
 
@@ -13,5 +14,5 @@ $database = new MySQLSwooleDatabase(
     'hello_world',
     intdiv(512, swoole_cpu_num())
 );
-$application = new Application($database);
+$application = new Application($database, new ArrayCachePool);
 SwooleBootstrap::run('0.0.0.0', 8080, $application, $database);

+ 3 - 1
frameworks/PHP/hamlet/workerman.php

@@ -1,6 +1,7 @@
 <?php
 
 use Benchmark\Application;
+use Cache\Adapter\PHPArray\ArrayCachePool;
 use Hamlet\Database\PDO\PDODatabase;
 use Hamlet\Http\Workerman\Bootstraps\WorkermanBootstrap;
 
@@ -11,5 +12,6 @@ $database = new PDODatabase(
     'benchmarkdbuser',
     'benchmarkdbpass'
 );
-$application = new Application($database);
+$cache = new ArrayCachePool;
+$application = new Application($database, $cache);
 WorkermanBootstrap::run('0.0.0.0', 8080, $application);