Browse Source

Added Swoole Postgres (#3838)

* Adding PostgreSQL support

* Update Swoole with postgres support

* Added Swoole postgres dockerfile

* Fix query warning

* Added Postgres lib support

* Disable the postgresql test until fixes a issue
Wulfklaue 7 years ago
parent
commit
d51b4d4856

+ 16 - 0
frameworks/PHP/swoole/swoole-postgres.dockerfile

@@ -0,0 +1,16 @@
+FROM php:7.2
+
+ENV SWOOLE_VERSION=2.1.3
+
+RUN     apt-get update && apt-get install -y libpq-dev \
+        && cd /tmp && curl -sSL "https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz" | tar xzf - \
+        && cd swoole-src-${SWOOLE_VERSION} \
+        && phpize && ./configure --enable-coroutine --enable-coroutine-postgresql > /dev/null && make > /dev/null && make install > /dev/null \
+        && docker-php-ext-enable swoole
+ 
+WORKDIR /swoole
+COPY swoole-server.php swoole-server.php
+COPY php.ini /usr/local/etc/php/
+
+CMD sed -i 's|NUMCORES|'"$(nproc)"'|g' swoole-server.php && \
+    php swoole-server.php

+ 159 - 82
frameworks/PHP/swoole/swoole-server.php

@@ -4,13 +4,127 @@ $server->set(array(
     'worker_num' => NUMCORES
     'worker_num' => NUMCORES
 ));
 ));
 
 
-$pool = new MySQLPool();
+$pool = new DatabasePool();
 
 
+/**
+ * The DB test
+ *
+ * @param string $database_type
+ * @param int    $queries
+ *
+ * @return string
+ */
+$db = function ($database_type, $queries = 0) use ($pool) {
+    $db = $pool->get($database_type);
+
+    // Read number of queries to run from URL parameter
+    $query_count = 1;
+    if ($queries > 0)
+        $query_count = $queries > 500 ? 500 : $queries;
+
+    // Create an array with the response string.
+    $arr = array();
+    // Define query
+    $stmt = $db->prepare('SELECT randomNumber FROM World WHERE id = ?');
+
+    // For each query, store the result set values in the response array
+    while (0 < $query_count--)
+    {
+        $id = mt_rand(1, 10000);
+        $ret = $stmt->execute(array($id));
+
+        // Store result in array.
+        $arr[] = array('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);
+};
+
+/**
+ * The Fortunes test
+ *
+ * @param string $database_type
+ *
+ * @return string
+ */
+$fortunes = function ($database_type) use ($pool) {
+    $db = $pool->get($database_type);
+
+    $fortune = [];
+    // Define query
+    $arr = $db->query('SELECT id, message FROM Fortune');
+    foreach ($arr as $row)
+        $fortune[$row['id']] = $row['message'];
+    $fortune[0] = 'Additional fortune added at request time.';
+    asort($fortune);
+
+    $html = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
+    foreach ($fortune as $id => $message)
+        $html .= "<tr><td>" . $id . "</td><td>" . htmlspecialchars($message, ENT_QUOTES, 'UTF-8') . "</td></tr>";
+
+    $html .= "</table></body></html>";
+
+    $pool->put($db);
+
+    return $html;
+};
+
+/**
+ * The Updates test
+ *
+ * @param string $database_type
+ * @param int    $queries
+ *
+ * @return string
+ */
+$updates = function ($database_type, $queries = 0) use ($pool) {
+    $db = $pool->get($database_type);
+
+    $query_count = 1;
+    if ($queries > 0)
+        $query_count = $queries > 500 ? 500 : $queries;
+
+    $arr = array();
+    $statement = $db->prepare('SELECT randomNumber FROM World WHERE id = ?');
+    $updateStatement = $db->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');
+
+    while (0 < $query_count--)
+    {
+        $id = mt_rand(1, 10000);
+        $randomNumber = mt_rand(1, 10000);
+        $ret = $statement->execute(array($id));
+
+        // Store result in array.
+        $world = array('id' => $id, 'randomNumber' => $ret[0]['randomNumber']);
+        $world['randomNumber'] = $randomNumber;
+        $updateStatement->execute(array($randomNumber, $id));
+
+        $arr[] = $world;
+    }
+
+    $pool->put($db);
+
+    return json_encode($arr);
+};
+
+/**
+ * On start of the PHP worker. One worker per server process is started.
+ */
 $server->on('workerStart', function () use (&$pool) {
 $server->on('workerStart', function () use (&$pool) {
     $pool->set_host_ip();
     $pool->set_host_ip();
 });
 });
 
 
-$server->on('request', function ($req, $res) use ($pool) {
+/**
+ * On every request to the (web)server, execute the following code
+ */
+$server->on('request', function ($req, $res) use ($db, $fortunes, $updates) {
 
 
     switch ($req->server['request_uri'])
     switch ($req->server['request_uri'])
     {
     {
@@ -25,91 +139,49 @@ $server->on('request', function ($req, $res) use ($pool) {
             break;
             break;
 
 
         case "/db":
         case "/db":
-            $db = $pool->get();
-
-            // Read number of queries to run from URL parameter
-            $query_count = 1;
-            if (isset($req->get['queries']) && $req->get['queries'] > 0)
-                $query_count = $req->get['queries'] > 500 ? 500 : $req->get['queries'];
-
-            // Create an array with the response string.
-            $arr = array();
-            // Define query
-            $stmt = $db->prepare('SELECT randomNumber FROM World WHERE id = ?');
-
-            // For each query, store the result set values in the response array
-            while (0 < $query_count--)
-            {
-                $id = mt_rand(1, 10000);
-                $ret = $stmt->execute(array($id));
-
-                // Store result in array.
-                $arr[] = array('id' => $id, 'randomNumber' => $ret[0]['randomNumber']);
-            }
-
-            // Use the PHP standard JSON encoder.
-            // http://www.php.net/manual/en/function.json-encode.php
-            if (count($arr) === 1)
-                $arr = $arr[0];
-
-            $pool->put($db);
-
             $res->header('Content-Type', 'application/json');
             $res->header('Content-Type', 'application/json');
-            $res->end(json_encode($arr));
+
+            if (isset($req->get['queries']))
+                $res->end($db("mysql", $req->get['queries']));
+            else
+                $res->end($db("mysql", -1));
             break;
             break;
 
 
         case "/fortunes":
         case "/fortunes":
-            $db = $pool->get();
-
-            $fortune = [];
-            // Define query
-            $arr = $db->query('SELECT id, message FROM Fortune');
-            foreach ($arr as $row)
-                $fortune[$row['id']] = $row['message'];
-            $fortune[0] = 'Additional fortune added at request time.';
-            asort($fortune);
-
-            $html = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
-            foreach ($fortune as $id => $message)
-                $html .= "<tr><td>" . $id . "</td><td>" . htmlspecialchars($message, ENT_QUOTES, 'UTF-8') . "</td></tr>";
-
-            $html .= "</table></body></html>";
-
-            $pool->put($db);
-
             $res->header('Content-Type', 'text/html; charset=utf-8');
             $res->header('Content-Type', 'text/html; charset=utf-8');
-            $res->end($html);
+            $res->end($fortunes("mysql"));
             break;
             break;
 
 
         case "/updates":
         case "/updates":
-            $db = $pool->get();
-
-            $query_count = 1;
-            if (isset($req->get['queries']) && $req->get['queries'] > 0)
-                $query_count = $req->get['queries'] > 500 ? 500 : $req->get['queries'];
-
-            $arr = array();
-            $statement = $db->prepare('SELECT randomNumber FROM World WHERE id = ?');
-            $updateStatement = $db->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');
+            $res->header('Content-Type', 'application/json');
 
 
-            while (0 < $query_count--)
-            {
-                $id = mt_rand(1, 10000);
-                $randomNumber = mt_rand(1, 10000);
-                $ret = $statement->execute(array($id));
+            if (isset($req->get['queries']))
+                $res->end($updates("mysql", $req->get['queries']));
+            else
+                $res->end($updates("mysql", -1));
+            break;
 
 
-                // Store result in array.
-                $world = array('id' => $id, 'randomNumber' => $ret[0]['randomNumber']);
-                $world['randomNumber'] = $randomNumber;
-                $updateStatement->execute(array($randomNumber, $id));
+        case "/db_postgres":
+            $res->header('Content-Type', 'application/json');
 
 
-                $arr[] = $world;
-            }
+            if (isset($req->get['queries']))
+                $res->end($db("postgres", $req->get['queries']));
+            else
+                $res->end($db("postgres", -1));
+            break;
 
 
-            $pool->put($db);
+        case "/fortunes_postgres":
+            $res->header('Content-Type', 'text/html; charset=utf-8');
+            $res->end($fortunes("postgres"));
+            break;
 
 
+        case "/updates_postgres":
             $res->header('Content-Type', 'application/json');
             $res->header('Content-Type', 'application/json');
-            $res->end(json_encode($arr));
+
+            if (isset($req->get['queries']))
+                $res->end($updates("postgres", $req->get['queries']));
+            else
+                $res->end($updates("postgres", -1));
             break;
             break;
     }
     }
 
 
@@ -118,11 +190,11 @@ $server->on('request', function ($req, $res) use ($pool) {
 $server->start();
 $server->start();
 
 
 /**
 /**
- * Class MySQLPool
+ * Class DatabasePool
  *
  *
  * Deal with the fact that Swoole 2.1.3 has no build in database pooling
  * Deal with the fact that Swoole 2.1.3 has no build in database pooling
  */
  */
-class MySQLPool
+class DatabasePool
 {
 {
     protected $pool;
     protected $pool;
     var $pool_count = 0;
     var $pool_count = 0;
@@ -141,7 +213,7 @@ class MySQLPool
 
 
     function set_host_ip()
     function set_host_ip()
     {
     {
-        if( empty( $this->server['host'] ) )
+        if (empty($this->server['host']))
         {
         {
             $tfb_database_ip = Swoole\Coroutine::gethostbyname('tfb-database');
             $tfb_database_ip = Swoole\Coroutine::gethostbyname('tfb-database');
             $this->server['host'] = $tfb_database_ip;
             $this->server['host'] = $tfb_database_ip;
@@ -154,21 +226,26 @@ class MySQLPool
         $this->pool_count++;
         $this->pool_count++;
     }
     }
 
 
-    function get()
+    function get($server_type)
     {
     {
-        if($this->pool_count > 0)
+        if ($this->pool_count > 0)
         {
         {
             $this->pool_count--;
             $this->pool_count--;
             return $this->pool->pop();
             return $this->pool->pop();
         }
         }
 
 
-        // No idle connection to create a new connection
-        $db = new Swoole\Coroutine\Mysql;
+        // No idle connection, time to create a new connection
+        if( $server_type == "mysql" )
+            $db = new Swoole\Coroutine\Mysql;
+
+        if( $server_type == "postgres" )
+            $db = new Swoole\Coroutine\PostgreSql;
+
         $db->connect($this->server);
         $db->connect($this->server);
 
 
         if ($db == false)
         if ($db == false)
             return false;
             return false;
-        else
-            return $db;
+
+        return $db;
     }
     }
 }
 }