Browse Source

Added openswoole (#6949)

Bruce Dou 3 years ago
parent
commit
3a319de511

+ 102 - 0
frameworks/PHP/openswoole/README.md

@@ -0,0 +1,102 @@
+<h1>
+    <img width="200" height="120" align="center" alt="Open Swoole Logo" src="https://www.swoole.co.uk/images/swoole-logo.svg" />
+</h1>
+
+[![lib-openswoole](https://github.com/openswoole/swoole-src/workflows/lib-openswoole/badge.svg)](https://github.com/openswoole/swoole-src/actions?query=workflow%3Alib-openswoole)
+[![ext-openswoole](https://github.com/openswoole/swoole-src/workflows/ext-openswoole/badge.svg)](https://github.com/openswoole/swoole-src/actions?query=workflow%3Aext-openswoole)
+[![test-linux](https://github.com/openswoole/swoole-src/workflows/test-linux/badge.svg)](https://github.com/openswoole/swoole-src/actions?query=workflow%3Atest-linux)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/23970/badge.svg)](https://scan.coverity.com/projects/open-swoole-src)
+[![codecov](https://codecov.io/gh/openswoole/swoole-src/branch/master/graph/badge.svg)](https://codecov.io/gh/openswoole/swoole-src)
+
+**Open Swoole (since 2017) is a programmatic server for PHP with async IO, coroutines and fibers: secure, reliable, high performance**
+
+## Documentation & Community
+
++ __Documentation__: <https://www.swoole.co.uk/docs>
++ __Twitter__: <https://twitter.com/openswoole>
++ __Join Slack Group__: <https://goo.gl/forms/wooTTDmhbu30x4qC3>
++ __Join Discord Channel__: <https://discord.gg/5QC57RNPpw>
++ __IDE Helper & API__: <https://github.com/openswoole/ide-helper>
+
+## Installation
+
+> As with any open source project, Open Swoole always provides the most reliable stability and the most powerful features in **the latest released version**. Please ensure as much as possible that you are using the latest version.
+
+### Compiling requirements
+
++ Linux, OS X or Cygwin, WSL
++ PHP 7.2.0 or later (The higher the version, the better the performance.)
++ GCC 4.8 or later
+
+### 1. Install with PECL (beginners)
+
+```shell
+pecl install openswoole
+```
+
+### 2. Install from source (recommended)
+
+Please download the source packages from [Releases](https://github.com/openswoole/swoole-src/releases) or:
+
+```shell
+git clone https://github.com/openswoole/swoole-src.git && \
+cd swoole-src
+git checkout v4.8.0
+```
+
+Compile and install at the source folder:
+
+```shell
+phpize && \
+./configure && \
+make && make install
+```
+
+#### Enable extension in PHP
+
+After compiling and installing the openswoole extension, you have to add a new line `extension=openswoole.so` to `php.ini` to enable Open Swoole. It is recommended to be added after all the other extensions because openswoole may depend on extensions: sockets, mysqlnd, curl etc.
+
+#### Extra compile configurations
+
+> for example: `./configure --enable-openssl --enable-sockets`
+
++ `--enable-openssl` or `--with-openssl-dir=DIR`
++ `--enable-sockets`
++ `--enable-http2`
++ `--enable-mysqlnd` (need mysqlnd, it just for supporting `$mysql->escape` method)
++ `--enable-swoole-json`
++ `--enable-swoole-curl`
++ `--with-postgres[=DIR]`
+
+### Upgrade
+
+>  If you upgrade from source, don't forget to `make clean` before you upgrade your swoole
+
+1. `pecl upgrade openswoole`
+2. `cd swoole-src && git pull && make clean && make && sudo make install`
+3. if you have changed PHP version, please re-run `phpize clean && phpize` then try to compile
+
+## Call for Contributors
+
+If you like to involve the maintenance of this repo, it is better to get started by submitting PR, you will be invited to the dev group once there are significant contributions. Or join Slack group firstly, the team will provide mentoring and internal support to help you get started.
+
+* [Report issues and feedback](https://github.com/openswoole/swoole-src/issues)
+* Submit fixes, features via Pull Request
+
+This project exists thanks to all the historical [[Contributors](https://github.com/openswoole/swoole-src/graphs/contributors)].
+
+## Security issues
+
+Security issues should be reported privately, via email, to the Open Swoole develop team [[email protected]](mailto:[email protected]). You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message.
+
+## Frameworks & Components
+
+> PR are welcome if your framework is using openswoole
+ 
+ - [**Laravel Octane**](https://laravel.com/docs/8.x/octane) Laravel Octane supercharges your application's performance by serving your application using high-powered application servers.
+ - [**PHP Runtime**](https://github.com/php-runtime) make it easy to run any kind of PHP Application (Symfony, Laravel, PSR7, Native) with all kinds of Runtimes like OpenSwoole, Bref, Google Cloud Functions, Roadrunner and React PHP with minimal configuration.
+ - [**Mezzio Swoole**](https://docs.mezzio.dev/mezzio-swoole/) allows you to run Mezzio and [PSR-15](https://www.php-fig.org/psr/psr-15/) applications on Open Swoole.
+
+## License
+
+Apache License Version 2.0 see http://www.apache.org/licenses/LICENSE-2.0.html

+ 70 - 0
frameworks/PHP/openswoole/benchmark_config.json

@@ -0,0 +1,70 @@
+{
+  "framework": "openswoole",
+  "tests": [{
+    "default": {
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "MySQL",
+      "framework": "openswoole",
+      "language": "PHP",
+      "flavor": "PHP8.1",
+      "orm": "Raw",
+      "platform": "openswoole",
+      "webserver": "none",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Open Swoole",
+      "notes": "",
+      "versus": "php"
+    },
+    "postgres": {
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "Postgres",
+      "framework": "openswoole",
+      "language": "PHP",
+      "flavor": "PHP8",
+      "orm": "Raw",
+      "platform": "openswoole",
+      "webserver": "none",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Open Swoole Postgres",
+      "notes": "",
+      "versus": "php"
+    },
+    "no-async": {
+      "db_url": "/db",
+      "query_url": "/query?q=",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates?q=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "MySQL",
+      "framework": "openswoole",
+      "language": "PHP",
+      "flavor": "PHP8.1",
+      "orm": "Raw",
+      "platform": "openswoole",
+      "webserver": "none",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Open Swoole no-async",
+      "notes": "Without async db pool connection",
+      "versus": "php"
+    }
+  }]
+}

+ 49 - 0
frameworks/PHP/openswoole/config.toml

@@ -0,0 +1,49 @@
+[framework]
+name = "openswoole"
+
+[main]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/db?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+approach = "Realistic"
+classification = "Platform"
+database = "MySQL"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "openswoole"
+webserver = "none"
+versus = "php"
+
+[postgres]
+urls.db = "/db"
+urls.query = "/db?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+approach = "Realistic"
+classification = "Platform"
+database = "Postgres"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "openswoole"
+webserver = "none"
+versus = "php"
+
+[no-async]
+urls.db = "/db"
+urls.query = "/query?q="
+urls.update = "/updates?q="
+urls.fortune = "/fortunes"
+approach = "Realistic"
+classification = "Platform"
+database = "MySQL"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "openswoole"
+webserver = "none"
+versus = "php"

+ 116 - 0
frameworks/PHP/openswoole/db-no-async.php

@@ -0,0 +1,116 @@
+<?php
+class Db
+{
+    public static PDOStatement $db;
+    public static PDOStatement $fortune;
+    public static PDOStatement $random;
+    public static PDOStatement $update;
+
+    public static function init()
+    {
+        $pdo = new PDO(
+            "mysql:host=tfb-database;dbname=hello_world",
+            "benchmarkdbuser",
+            "benchmarkdbpass",
+            [
+                PDO::ATTR_DEFAULT_FETCH_MODE  => PDO::FETCH_ASSOC,
+                PDO::ATTR_ERRMODE             => PDO::ERRMODE_EXCEPTION,
+                PDO::ATTR_EMULATE_PREPARES    => false
+            ]
+        );
+
+        self::$db        = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
+        self::$fortune   = $pdo->prepare('SELECT id,message FROM Fortune');
+        self::$random    = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
+        self::$update    = $pdo->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');
+    }
+}
+
+/**
+ * The DB test
+ *
+ * @return string
+ */
+function db(): string
+{
+    Db::$db->execute([mt_rand(1, 10000)]);
+    return json_encode(Db::$db->fetch(), JSON_NUMERIC_CHECK);
+}
+
+/**
+ * The Queries test
+ *
+ * @param int $queries
+ *
+ * @return string
+ */
+function query(int $queries = 1): string
+{
+    // Read number of queries to run from URL parameter
+    $query_count = 1;
+    if ($queries > 1) {
+        $query_count = $queries > 500 ? 500 : $queries;
+    }
+
+    // Create an array with the response string.
+    $arr = [];
+
+    // For each query, store the result set values in the response array
+    while ($query_count--) {
+        DB::$db->execute([mt_rand(1, 10000)]);
+        $arr[] = Db::$db->fetch();
+    }
+
+    return json_encode($arr, JSON_NUMERIC_CHECK);
+}
+
+/**
+ * The Fortunes test
+ *
+ * @return string
+ */
+function fortunes(): string
+{
+    $fortune = [];
+    Db::$fortune->execute();
+    $fortune = Db::$fortune->fetchAll(PDO::FETCH_KEY_PAIR);
+
+    $fortune[0] = 'Additional fortune added at request time.';
+    asort($fortune);
+
+    $html = '';
+    foreach ($fortune as $id => $message) {
+        $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
+        $html .= "<tr><td>$id</td><td>$message</td></tr>";
+    }
+
+    return "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>";
+}
+
+/**
+ * The Updates test
+ *
+ * @param int $queries
+ *
+ * @return string
+ */
+function updates(int $queries): string
+{
+    $query_count = 1;
+    if ($queries > 1) {
+        $query_count = $queries > 500 ? 500 : $queries;
+    }
+
+    while ($query_count--) {
+        $id = mt_rand(1, 10000);
+        Db::$random->execute([$id]);
+
+        $world = ["id" => $id, "randomNumber" => Db::$random->fetchColumn()];
+        $world['randomNumber'] = mt_rand(1, 10000);
+        Db::$update->execute([$world['randomNumber'], $world['id']]);
+
+        $arr[] = $world;
+    }
+
+    return json_encode($arr, JSON_NUMERIC_CHECK);
+}

+ 15 - 0
frameworks/PHP/openswoole/openswoole-no-async.dockerfile

@@ -0,0 +1,15 @@
+FROM php:8.1-rc-cli
+
+RUN pecl install openswoole > /dev/null && \
+    docker-php-ext-enable openswoole
+
+RUN docker-php-ext-install opcache pdo_mysql > /dev/null
+
+ADD ./ /openswoole
+WORKDIR /openswoole
+
+COPY php.ini /usr/local/etc/php/
+
+EXPOSE 8080
+
+CMD php swoole-server-noasync.php

+ 22 - 0
frameworks/PHP/openswoole/openswoole-postgres.dockerfile

@@ -0,0 +1,22 @@
+FROM php:8.1-rc-cli
+
+RUN docker-php-ext-install opcache  > /dev/null
+
+ENV SWOOLE_VERSION 4.8.0
+
+RUN     apt-get update && apt-get install -y libpq-dev \
+        && cd /tmp && curl -sSL "https://github.com/openswoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz" | tar xzf - \
+        && cd swoole-src-${SWOOLE_VERSION} \
+        && phpize && ./configure --with-postgres > /dev/null && make > /dev/null && make install > /dev/null \
+        && docker-php-ext-enable openswoole
+ 
+WORKDIR /openswoole
+
+COPY swoole-server.php swoole-server.php
+RUN sed -i "s|_postgres||g" swoole-server.php
+
+COPY php.ini /usr/local/etc/php/
+
+EXPOSE 8080
+
+CMD php swoole-server.php

+ 18 - 0
frameworks/PHP/openswoole/openswoole.dockerfile

@@ -0,0 +1,18 @@
+FROM php:8.1-rc-cli
+
+RUN pecl install openswoole > /dev/null && \
+    docker-php-ext-enable openswoole
+
+RUN docker-php-ext-install opcache  > /dev/null
+
+WORKDIR /openswoole
+
+COPY swoole-server.php swoole-server.php
+RUN sed -i "s|DatabasePool('postgres|DatabasePool('mysql|g" swoole-server.php
+RUN sed -i "s|_mysql||g" swoole-server.php
+
+COPY php.ini /usr/local/etc/php/
+
+EXPOSE 8080
+
+CMD php swoole-server.php

+ 6 - 0
frameworks/PHP/openswoole/php.ini

@@ -0,0 +1,6 @@
+opcache.enable_cli=1
+opcache.validate_timestamps=0
+memory_limit = 512M
+
+opcache.jit_buffer_size=128M
+opcache.jit=tracing

+ 69 - 0
frameworks/PHP/openswoole/swoole-server-noasync.php

@@ -0,0 +1,69 @@
+<?php
+require_once __DIR__.'/db-no-async.php';
+
+use Swoole\Http\Request;
+use Swoole\Http\Response;
+
+$server = new swoole_http_server('0.0.0.0', 8080, SWOOLE_BASE);
+$server->set([
+    'worker_num' => swoole_cpu_num() * 4,
+    'log_file' => '/dev/null',
+    'log_level' => 5,
+    'open_tcp_nodelay' => true,
+]);
+
+/**
+ * On start of the PHP worker. One worker per server process is started.
+ */
+$server->on('workerStart', function () {
+    Db::init();
+});
+
+/**
+ * On every request to the (web)server, execute the following code
+ */
+$server->on('request', static function (Request $req, Response $res) {
+    try {
+        switch ($req->server['request_uri']) {
+            case '/json':
+                $res->header('Content-Type', 'application/json');
+                $res->end(json_encode(['message' => 'Hello, World!']));
+                break;
+
+            case '/plaintext':
+                $res->header('Content-Type', 'text/plain; charset=utf-8');
+                $res->end('Hello, World!');
+                break;
+
+            case '/db':
+                $res->header('Content-Type', 'application/json');
+                $res->end(db());
+                break;
+            
+            case '/query':
+                $res->header('Content-Type', 'application/json');
+                $res->end(query((int) $req->get['q'] ?? 1));
+                break;
+
+            case '/fortunes':
+                $res->header('Content-Type', 'text/html; charset=utf-8');
+                $res->end(fortunes());
+                break;
+
+            case '/updates':
+                $res->header('Content-Type', 'application/json');
+                $res->end(updates((int) $req->get['q'] ?? 1));
+                break;
+
+            default:
+                $res->status(404);
+                $res->end('Not Found.');
+        }
+
+    } catch (\Throwable $e) {
+        $res->status(500);
+        $res->end('code ' . $e->getCode(). 'msg: '. $e->getMessage());
+    }
+});
+
+$server->start();

+ 371 - 0
frameworks/PHP/openswoole/swoole-server.php

@@ -0,0 +1,371 @@
+<?php
+
+error_reporting(0);
+
+use Swoole\Http\Request;
+use Swoole\Http\Response;
+
+$server = new swoole_http_server('0.0.0.0', 8080, SWOOLE_BASE);
+$server->set([
+    'worker_num' => swoole_cpu_num(),
+    'log_file' => '/dev/null',
+    'log_level' => 5,
+    'open_tcp_nodelay' => true,
+]);
+
+$pool = new \DatabasePool('postgres');
+
+/**
+ * On start of the PHP worker. One worker per server process is started.
+ */
+$server->on('workerStart', function ($srv) use ($pool) {
+    $pool->init(\intdiv(512, $srv->setting['worker_num']));
+});
+
+/**
+ * The DB test
+ *
+ * @param string $database_type
+ * @param int $queries
+ *
+ * @return string
+ */
+$db_postgres = function (int $queries = 0) use ($pool): string {
+    $db = $pool->get();
+    // Read number of queries to run from URL parameter
+    $query_count = 1;
+    if ($queries > 1) {
+        $query_count = $queries > 500 ? 500 : $queries;
+    }
+
+    // Create an array with the response string.
+    $arr = [];
+
+    $db->s ??= $db->prepare('s', 'SELECT id, randomnumber FROM World WHERE id = $1');
+
+    // For each query, store the result set values in the response array
+    while ($query_count--) {
+        $id = mt_rand(1, 10000);
+        $res = $db->execute('s', [$id]);
+        $ret = $db->fetchAssoc($res);
+        // Store result in array.
+        $arr[] = ['id' => $id, 'randomnumber' => $ret['randomnumber']];
+    }
+
+    // Use the PHP standard JSON encoder.
+    // http://www.php.net/manual/en/function.json-encode.php
+    if ($queries === -1) {
+        $arr = $arr[0];
+    }
+
+    $pool->put($db);
+
+    return \json_encode($arr, JSON_NUMERIC_CHECK);
+};
+
+/**
+ * The Fortunes test
+ *
+ * @param string $database_type
+ *
+ * @return string
+ */
+$fortunes_postgres = function () use ($pool): string {
+    $db = $pool->get();
+
+    $fortune = [];
+
+    $db->f ??= $db->prepare('f', 'SELECT id, message FROM Fortune');
+    $res = $db->execute('f', []);
+    $arr = $db->fetchAll($res);
+
+    foreach ($arr as $row) {
+        $fortune[$row['id']] = $row['message'];
+    }
+    $fortune[0] = 'Additional fortune added at request time.';
+    \asort($fortune);
+
+    $html = '';
+    foreach ($fortune as $id => $message) {
+        $message = \htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
+        $html .= "<tr><td>{$id}</td><td>{$message}</td></tr>";
+    }
+
+    $pool->put($db);
+
+    return '<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>'
+            .$html.
+            '</table></body></html>';
+};
+
+/**
+ * The Updates test
+ *
+ * @param string $database_type
+ * @param int $queries
+ *
+ * @return string
+ */
+$updates_postgres = function (int $queries = 0) use ($pool): string {
+    $db = $pool->get();
+
+    $query_count = 1;
+    if ($queries > 1) {
+        $query_count = $queries > 500 ? 500 : $queries;
+    }
+
+    $arr = [];
+
+    $db->us ??= $db->prepare('us', 'SELECT id,randomnumber FROM World WHERE id = $1');
+    $db->uu ??= $db->prepare('uu', 'UPDATE World SET randomnumber = $1 WHERE id = $2');
+
+    while ($query_count--) {
+        $id = \mt_rand(1, 10000);
+        $randomNumber = \mt_rand(1, 10000);
+        $res = $db->execute('us', [$id]);
+        $ret = $db->fetchAssoc($res);
+        // Store result in array.
+        $world = ['id' => $id, 'randomnumber' => $ret['randomnumber']];
+        $world['randomnumber'] = $randomNumber;
+        $res = $db->execute('uu', [$randomNumber, $id]);
+        $arr[] = $world;
+    }
+
+    $pool->put($db);
+
+    return \json_encode($arr, JSON_NUMERIC_CHECK);
+};
+
+/**
+ * The DB test
+ *
+ * @param string $database_type
+ * @param int $queries
+ *
+ * @return string
+ */
+$db_mysql = function (int $queries = 0) use ($pool): string {
+    $db = $pool->get();
+
+    // Read number of queries to run from URL parameter
+    $query_count = 1;
+    if ($queries > 1) {
+        $query_count = $queries > 500 ? 500 : $queries;
+    }
+
+    // Create an array with the response string.
+    $arr = [];
+    // Define query
+    $db->db_test ??= $db->prepare('SELECT id, randomNumber FROM World WHERE id = ?');
+
+    // For each query, store the result set values in the response array
+    while ($query_count--) {
+        $id = \mt_rand(1, 10000);
+        $ret = $db->db_test->execute([$id]);
+
+        // Store result in array.
+        $arr[] = ['id' => $id, 'randomNumber' => $ret[0]['randomNumber']];
+    }
+
+    // Use the PHP standard JSON encoder.
+    // http://www.php.net/manual/en/function.json-encode.php
+    if ($queries === -1) {
+        $arr = $arr[0];
+    }
+
+    $pool->put($db);
+
+    return \json_encode($arr, JSON_NUMERIC_CHECK);
+};
+
+/**
+ * The Fortunes test
+ *
+ * @param string $database_type
+ *
+ * @return string
+ */
+$fortunes_mysql = function () use ($pool): string {
+    $db = $pool->get();
+
+    $fortune = [];
+
+    $db->fortune_test ??= $db->prepare('SELECT id, message FROM Fortune');
+    $arr = $db->fortune_test->execute();
+
+    foreach ($arr as $row) {
+        $fortune[$row['id']] = $row['message'];
+    }
+    $fortune[0] = 'Additional fortune added at request time.';
+    \asort($fortune);
+
+    $html = '';
+    foreach ($fortune as $id => $message) {
+        $message = \htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
+        $html .= "<tr><td>{$id}</td><td>{$message}</td></tr>";
+    }
+
+    $pool->put($db);
+
+    return '<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>'
+            .$html.
+            '</table></body></html>';
+};
+
+/**
+ * The Updates test
+ *
+ * @param string $database_type
+ * @param int $queries
+ *
+ * @return string
+ */
+$updates_mysql = function (int $queries = 0) use ($pool): string {
+    $db = $pool->get();
+
+    $query_count = 1;
+    if ($queries > 1) {
+        $query_count = $queries > 500 ? 500 : $queries;
+    }
+
+    $arr = [];
+    $db->updates_test_select ??= $db->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
+    $db->updates_test_update ??= $db->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');
+
+    while ($query_count--) {
+        $id = \mt_rand(1, 10000);
+        $randomNumber = \mt_rand(1, 10000);
+        $ret = $db->updates_test_select->execute([$id]);
+
+        // Store result in array.
+        $world = ['id' => $id, 'randomNumber' => $ret[0]['randomNumber']];
+        $world['randomNumber'] = $randomNumber;
+        $db->updates_test_update->execute([$randomNumber, $id]);
+
+        $arr[] = $world;
+    }
+
+    $pool->put($db);
+
+    return \json_encode($arr, JSON_NUMERIC_CHECK);
+};
+
+
+/**
+ * On every request to the (web)server, execute the following code
+ */
+$server->on('request', function (Request $req, Response $res) use ($db, $fortunes, $updates) {
+    try {
+        switch ($req->server['request_uri']) {
+            case '/json':
+                $res->header('Content-Type', 'application/json');
+                $res->end(json_encode(['message' => 'Hello, World!']));
+                break;
+
+            case '/plaintext':
+                $res->header('Content-Type', 'text/plain; charset=utf-8');
+                $res->end('Hello, World!');
+                break;
+
+            case '/db':
+                $res->header('Content-Type', 'application/json');
+
+                if (isset($req->get['queries'])) {
+                    $res->end($db((int)$req->get['queries']));
+                } else {
+                    $res->end($db(-1));
+                }
+                break;
+
+            case '/fortunes':
+                $res->header('Content-Type', 'text/html; charset=utf-8');
+                $res->end($fortunes());
+                break;
+
+            case '/updates':
+                $res->header('Content-Type', 'application/json');
+
+                if (isset($req->get['queries'])) {
+                    $res->end($updates((int)$req->get['queries']));
+                } else {
+                    $res->end($updates(-1));
+                }
+                break;
+
+            default:
+                $res->status(404);
+                $res->end('Error 404');
+
+        }
+
+    } catch (\Throwable $e) {
+        $res->status(500);
+        $res->end('Error 500');
+    }
+});
+
+$server->start();
+
+/**
+ * Class DatabasePool
+ *
+ * Deal with the fact that Open Swoole 2.1.3 has no build in database pooling
+ */
+class DatabasePool
+{
+    private $server = [
+        'host' => '',
+        'user' => 'benchmarkdbuser',
+        'password' => 'benchmarkdbpass',
+        'database' => 'hello_world'
+    ];
+
+    private $pool;
+
+    private $type;
+
+    public function __construct($type)
+    {
+        $this->server['host'] = \gethostbyname('tfb-database');
+        $this->type = $type;
+    }
+
+    public function init($capacity)
+    {
+        $this->pool=new \Swoole\Coroutine\Channel($capacity);
+        while($capacity>0){
+            $db=$this->createDbInstance();
+            if($db!==false){
+                $this->pool->push($db);
+                $capacity--;
+            }
+        }
+    }
+
+    private function createDbInstance()
+    {
+        if ($this->type === 'postgres') {
+            $db = new Swoole\Coroutine\PostgreSql;
+            if ($db->connect("host={$this->server['host']} port=5432 dbname={$this->server['database']} user={$this->server['user']} password={$this->server['password']}")){
+                return $db;
+            }
+        } else if($this->type === 'mysql') {
+            $db = new Swoole\Coroutine\Mysql;
+            if ($db->connect($this->server)){
+                return $db;
+            }
+        }
+
+        return false;
+    }
+
+    public function put($db)
+    {
+        $this->pool->push($db);
+    }
+
+    public function get()
+    {
+        return $this->pool->pop();
+    }
+}