openswoole-server-postgres.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. require_once __DIR__.'/vendor/autoload.php';
  3. use OpenSwoole\Http\Request;
  4. use OpenSwoole\Http\Response;
  5. use OpenSwoole\Http\Server;
  6. use OpenSwoole\Util;
  7. use OpenSwoole\Core\Coroutine\Client\PostgresClientFactory;
  8. use OpenSwoole\Core\Coroutine\Client\PostgresConfig;
  9. use OpenSwoole\Core\Coroutine\Pool\ClientPool;
  10. $server = new Server('0.0.0.0', 8080, OpenSwoole\Server::SIMPLE_MODE);
  11. $server->set([
  12. 'worker_num' => Util::getCPUNum() * 2,
  13. 'log_file' => '/dev/null',
  14. 'log_level' => 5,
  15. 'open_tcp_nodelay' => true,
  16. ]);
  17. $pool = null;
  18. /**
  19. * On start of the PHP worker. One worker per server process is started.
  20. */
  21. $server->on('workerStart', function () use (&$pool) {
  22. $config = (new PostgresConfig())
  23. ->withHost('tfb-database')
  24. ->withDbname('hello_world')
  25. ->withUsername('benchmarkdbuser')
  26. ->withPassword('benchmarkdbpass');
  27. $pool = new ClientPool(PostgresClientFactory::class, $config, \intdiv(512, Util::getCPUNum() * 2));
  28. });
  29. /**
  30. * The DB test
  31. *
  32. * @param string $database_type
  33. * @param int $queries
  34. *
  35. * @return string
  36. */
  37. $db_postgres = function (int $queries = 0, $pool): string {
  38. $db = $pool->get();
  39. // Read number of queries to run from URL parameter
  40. $query_count = 1;
  41. if ($queries > 1) {
  42. $query_count = $queries > 500 ? 500 : $queries;
  43. }
  44. // Create an array with the response string.
  45. $arr = [];
  46. $db->prepare('s', 'SELECT id, randomnumber FROM World WHERE id = $1');
  47. // For each query, store the result set values in the response array
  48. while ($query_count--) {
  49. $id = mt_rand(1, 10000);
  50. $res = $db->execute('s', [$id]);
  51. $ret = $db->fetchAssoc($res);
  52. // Store result in array.
  53. $arr[] = ['id' => $id, 'randomnumber' => $ret['randomnumber']];
  54. }
  55. // Use the PHP standard JSON encoder.
  56. // http://www.php.net/manual/en/function.json-encode.php
  57. if ($queries === -1) {
  58. $arr = $arr[0];
  59. }
  60. $pool->put($db);
  61. return \json_encode($arr, JSON_NUMERIC_CHECK);
  62. };
  63. /**
  64. * The Fortunes test
  65. *
  66. * @param string $database_type
  67. *
  68. * @return string
  69. */
  70. $fortunes_postgres = function ($pool): string {
  71. $db = $pool->get();
  72. $fortune = [];
  73. $db->prepare('f', 'SELECT id, message FROM Fortune');
  74. $res = $db->execute('f', []);
  75. $arr = $db->fetchAll($res);
  76. foreach ($arr as $row) {
  77. $fortune[$row['id']] = $row['message'];
  78. }
  79. $fortune[0] = 'Additional fortune added at request time.';
  80. \asort($fortune);
  81. $html = '';
  82. foreach ($fortune as $id => $message) {
  83. $message = \htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
  84. $html .= "<tr><td>{$id}</td><td>{$message}</td></tr>";
  85. }
  86. $pool->put($db);
  87. return '<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>'
  88. .$html.
  89. '</table></body></html>';
  90. };
  91. /**
  92. * The Updates test
  93. *
  94. * @param string $database_type
  95. * @param int $queries
  96. *
  97. * @return string
  98. */
  99. $updates_postgres = function (int $queries = 0, $pool): string {
  100. $db = $pool->get();
  101. $query_count = 1;
  102. if ($queries > 1) {
  103. $query_count = $queries > 500 ? 500 : $queries;
  104. }
  105. $arr = [];
  106. $db->prepare('us', 'SELECT id,randomnumber FROM World WHERE id = $1');
  107. $db->prepare('uu', 'UPDATE World SET randomnumber = $1 WHERE id = $2');
  108. while ($query_count--) {
  109. $id = \mt_rand(1, 10000);
  110. $randomNumber = \mt_rand(1, 10000);
  111. $res = $db->execute('us', [$id]);
  112. $ret = $db->fetchAssoc($res);
  113. // Store result in array.
  114. $world = ['id' => $id, 'randomnumber' => $ret['randomnumber']];
  115. $world['randomnumber'] = $randomNumber;
  116. $res = $db->execute('uu', [$randomNumber, $id]);
  117. $arr[] = $world;
  118. }
  119. $pool->put($db);
  120. return \json_encode($arr, JSON_NUMERIC_CHECK);
  121. };
  122. /**
  123. * On every request to the (web)server, execute the following code
  124. */
  125. $server->on('request', function (Request $req, Response $res) use ($db_postgres, $fortunes_postgres, $updates_postgres, &$pool) {
  126. try {
  127. switch ($req->server['request_uri']) {
  128. case '/json':
  129. $res->header('Content-Type', 'application/json');
  130. $res->header('Server', 'os');
  131. $res->end(json_encode(['message' => 'Hello, World!']));
  132. break;
  133. case '/plaintext':
  134. $res->header('Content-Type', 'text/plain; charset=utf-8');
  135. $res->header('Server', 'os');
  136. $res->end('Hello, World!');
  137. break;
  138. case '/db':
  139. $res->header('Content-Type', 'application/json');
  140. $res->header('Server', 'os');
  141. if (isset($req->get['queries'])) {
  142. $res->end($db_postgres((int)$req->get['queries'], $pool));
  143. } else {
  144. $res->end($db_postgres(-1, $pool));
  145. }
  146. break;
  147. case '/fortunes':
  148. $res->header('Content-Type', 'text/html; charset=utf-8');
  149. $res->header('Server', 'os');
  150. $res->end($fortunes_postgres($pool));
  151. break;
  152. case '/updates':
  153. $res->header('Content-Type', 'application/json');
  154. $res->header('Server', 'os');
  155. if (isset($req->get['queries'])) {
  156. $res->end($updates_postgres((int)$req->get['queries'], $pool));
  157. } else {
  158. $res->end($updates_postgres(-1, $pool));
  159. }
  160. break;
  161. default:
  162. $res->status(404);
  163. $res->end('Error 404');
  164. }
  165. } catch (\Throwable $e) {
  166. $res->status(500);
  167. $res->end('Error 500');
  168. }
  169. });
  170. $server->start();