Skip to content

Commit a65d01a

Browse files
authored
[PHP] Add Swoole and Swow as event-driven stress tests for Workerman. (#9382)
* Add Swoole and Swow as event-driven stress tests for Workerman. * Text and json requests using Select event-driven
1 parent 7aca29c commit a65d01a

24 files changed

+730
-381
lines changed

frameworks/PHP/workerman/Date.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use Workerman\Timer;
4+
5+
class Date
6+
{
7+
public $date = null;
8+
public function __construct()
9+
{
10+
$this->date = gmdate('D, d M Y H:i:s').' GMT';
11+
Timer::add(1, function() {
12+
$this->date = gmdate('D, d M Y H:i:s').' GMT';
13+
});
14+
}
15+
}

frameworks/PHP/workerman/Mysql.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
class Mysql
4+
{
5+
6+
protected PDO $pdo;
7+
protected PDOStatement $world;
8+
protected PDOStatement $fortune;
9+
protected PDOStatement $update;
10+
11+
public function __construct()
12+
{
13+
$this->pdo = new PDO(
14+
'mysql:host=tfb-database;dbname=hello_world',
15+
'benchmarkdbuser',
16+
'benchmarkdbpass',
17+
[
18+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
19+
PDO::ATTR_EMULATE_PREPARES => false
20+
]
21+
);
22+
$this->world = $this->pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?');
23+
$this->fortune = $this->pdo->prepare('SELECT id,message FROM Fortune');
24+
$this->update = $this->pdo->prepare('UPDATE World SET randomNumber=? WHERE id=?');
25+
}
26+
27+
function db(): array
28+
{
29+
$this->world->execute([mt_rand(1, 10000)]);
30+
return $this->world->fetch();
31+
}
32+
33+
function query($request): array
34+
{
35+
$query_count = 1;
36+
$q = (int)$request->get('q');
37+
if ($q > 1) {
38+
$query_count = min($q, 500);
39+
}
40+
$arr = [];
41+
while ($query_count--) {
42+
$this->world->execute([mt_rand(1, 10000)]);
43+
$arr[] = $this->world->fetch();
44+
}
45+
return $arr;
46+
}
47+
48+
function update($request): array
49+
{
50+
$query_count = 1;
51+
$q = (int)$request->get('q');
52+
if ($q > 1) {
53+
$query_count = min($q, 500);
54+
}
55+
$arr = [];
56+
while ($query_count--) {
57+
$id = mt_rand(1, 10000);
58+
$this->world->execute([$id]);
59+
$item = $this->world->fetch();
60+
$this->update->execute(
61+
[$item['randomNumber'] = mt_rand(1, 10000), $id]
62+
);
63+
$arr[] = $item;
64+
}
65+
return $arr;
66+
}
67+
68+
function fortune(): string
69+
{
70+
$this->fortune->execute();
71+
$arr = $this->fortune->fetchAll(PDO::FETCH_KEY_PAIR);
72+
$arr[0] = 'Additional fortune added at request time.';
73+
asort($arr);
74+
$html = '';
75+
foreach ($arr as $id => $message) {
76+
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
77+
$html .= "<tr><td>$id</td><td>$message</td></tr>";
78+
}
79+
return "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>";
80+
}
81+
82+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
use Swoole\Database\PDOConfig;
4+
use Swoole\Database\PDOPool;
5+
class MysqlSwoole
6+
{
7+
8+
protected Pool|PDOPool $pool;
9+
10+
public function __construct($size)
11+
{
12+
$config = (new PDOConfig())
13+
->withDriver('mysql')
14+
->withHost('tfb-database')
15+
->withPort(3306)
16+
->withDbName('hello_world')
17+
->withUsername('benchmarkdbuser')
18+
->withPassword('benchmarkdbpass');
19+
$this->pool = new PDOPool($config, $size);
20+
}
21+
22+
function db(): array
23+
{
24+
$pdo = $this->pool->get();
25+
$stmt = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?');
26+
$stmt->execute([mt_rand(1, 10000)]);
27+
$result = $stmt->fetch(PDO::FETCH_ASSOC);
28+
$this->pool->put($pdo);
29+
return $result;
30+
}
31+
32+
function query($request): array
33+
{
34+
$query_count = 1;
35+
$q = (int)$request->get('q');
36+
if ($q > 1) {
37+
$query_count = min($q, 500);
38+
}
39+
$pdo = $this->pool->get();
40+
$stmt = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?');
41+
$arr = [];
42+
while ($query_count--) {
43+
$stmt->execute([mt_rand(1, 10000)]);
44+
$arr[] = $stmt->fetch(PDO::FETCH_ASSOC);
45+
}
46+
$this->pool->put($pdo);
47+
return $arr;
48+
}
49+
50+
function update($request): array
51+
{
52+
$query_count = 1;
53+
$q = (int)$request->get('q');
54+
if ($q > 1) {
55+
$query_count = min($q, 500);
56+
}
57+
$arr = [];
58+
$pdo = $this->pool->get();
59+
$world = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?');
60+
$update = $pdo->prepare('UPDATE World SET randomNumber=? WHERE id=?');
61+
while ($query_count--) {
62+
$id = mt_rand(1, 10000);
63+
$world->execute([$id]);
64+
$item = $world->fetch(PDO::FETCH_ASSOC);
65+
$update->execute(
66+
[$item['randomNumber'] = mt_rand(1, 10000), $id]
67+
);
68+
$arr[] = $item;
69+
}
70+
$this->pool->put($pdo);
71+
return $arr;
72+
}
73+
74+
function fortune(): string
75+
{
76+
$pdo = $this->pool->get();
77+
$stmt = $pdo->prepare('SELECT id,message FROM Fortune');
78+
$stmt->execute();
79+
$arr = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
80+
$this->pool->put($pdo);
81+
$arr[0] = 'Additional fortune added at request time.';
82+
asort($arr);
83+
$html = '';
84+
foreach ($arr as $id => $message) {
85+
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
86+
$html .= "<tr><td>$id</td><td>$message</td></tr>";
87+
}
88+
return "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>";
89+
}
90+
91+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Swoole\Database\PDOPool;
4+
class MysqlSwow extends MysqlSwoole
5+
{
6+
7+
public function __construct($size)
8+
{
9+
$this->pool = new Pool("mysql:host=tfb-database;dbname=hello_world", 'benchmarkdbuser', 'benchmarkdbpass', $size);
10+
}
11+
12+
}

frameworks/PHP/workerman/Pgsql.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
class Pgsql extends Mysql
4+
{
5+
protected PDO $pdo;
6+
protected PDOStatement $world;
7+
protected PDOStatement $fortune;
8+
protected PDOStatement $update;
9+
protected PDOStatement $random;
10+
protected array $updates = [];
11+
12+
public function __construct()
13+
{
14+
$this->pdo = new PDO(
15+
'pgsql:host=tfb-database;dbname=hello_world',
16+
'benchmarkdbuser',
17+
'benchmarkdbpass',
18+
[
19+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
20+
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
21+
PDO::ATTR_EMULATE_PREPARES => false
22+
]
23+
);
24+
$this->world = $this->random = $this->pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?');
25+
$this->fortune = $this->pdo->prepare('SELECT id,message FROM Fortune');
26+
$this->update = $this->pdo->prepare('UPDATE World SET randomNumber=? WHERE id=?');
27+
}
28+
29+
function update($request): array
30+
{
31+
$query_count = 1;
32+
$q = (int)$request->get('q');
33+
if ($q > 1) {
34+
$query_count = min($q, 500);
35+
}
36+
$worlds = [];
37+
while ($query_count--) {
38+
$this->random->execute([\mt_rand(1, 10000)]);
39+
$world = $this->random->fetch();
40+
$world['randomNumber'] = \mt_rand(1, 10000);
41+
$worlds[] = $world;
42+
}
43+
$rows = count($worlds);
44+
45+
if (!isset($this->updates[$rows])) {
46+
$sql = 'UPDATE world SET randomNumber = CASE id'
47+
. str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $rows)
48+
. 'END WHERE id IN ('
49+
. str_repeat('?::INTEGER,', $rows - 1) . '?::INTEGER)';
50+
51+
$this->updates[$rows] = $this->pdo->prepare($sql);
52+
}
53+
54+
$val = [];
55+
$keys = [];
56+
foreach ($worlds as $world) {
57+
$val[] = $keys[] = $world['id'];
58+
$val[] = $world['randomNumber'];
59+
}
60+
61+
$this->updates[$rows]->execute([...$val, ...$keys]);
62+
return $worlds;
63+
}
64+
65+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
use Swoole\Database\PDOConfig;
4+
use Swoole\Database\PDOPool;
5+
class PgsqlSwoole extends MysqlSwoole
6+
{
7+
8+
protected Pool|PDOPool $pool;
9+
10+
public function __construct($size)
11+
{
12+
$config = (new PDOConfig())
13+
->withDriver('pgsql')
14+
->withHost('tfb-database')
15+
->withPort(5432)
16+
->withDbName('hello_world')
17+
->withUsername('benchmarkdbuser')
18+
->withPassword('benchmarkdbpass');
19+
20+
$this->pool = new PDOPool($config, $size);
21+
}
22+
23+
24+
function update($request): array
25+
{
26+
$query_count = 1;
27+
$q = (int)$request->get('q');
28+
if ($q > 1) {
29+
$query_count = min($q, 500);
30+
}
31+
$worlds = [];
32+
$pdo = $this->pool->get();
33+
$random = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?');
34+
while ($query_count--) {
35+
$random->execute([mt_rand(1, 10000)]);
36+
$world = $random->fetch(PDO::FETCH_ASSOC);
37+
$world['randomNumber'] = mt_rand(1, 10000);
38+
$worlds[] = $world;
39+
}
40+
$rows = count($worlds);
41+
42+
$sql = 'UPDATE world SET randomNumber = CASE id'
43+
. str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $rows)
44+
. 'END WHERE id IN ('
45+
. str_repeat('?::INTEGER,', $rows - 1) . '?::INTEGER)';
46+
47+
$update = $pdo->prepare($sql);
48+
49+
$val = [];
50+
$keys = [];
51+
foreach ($worlds as $world) {
52+
$val[] = $keys[] = $world['id'];
53+
$val[] = $world['randomNumber'];
54+
}
55+
56+
$update->execute([...$val, ...$keys]);
57+
$this->pool->put($pdo);
58+
return $worlds;
59+
}
60+
61+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Swoole\Database\PDOPool;
4+
class PgsqlSwow extends MysqlSwow
5+
{
6+
7+
public function __construct($size)
8+
{
9+
$this->pool = new Pool("pgsql:host=tfb-database;dbname=hello_world", 'benchmarkdbuser', 'benchmarkdbpass', $size);
10+
}
11+
12+
}

frameworks/PHP/workerman/Pool.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
use Swow\Channel;
4+
5+
class Pool
6+
{
7+
8+
protected static Channel $channel;
9+
10+
public function __construct($dsn, $username, $password, $size)
11+
{
12+
static::$channel = new Channel($size);
13+
for ($i = 0; $i < $size; $i++) {
14+
static::$channel->push(new PDO($dsn, $username, $password,[
15+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
16+
]));
17+
}
18+
}
19+
20+
public function get(): PDO
21+
{
22+
return static::$channel->pop();
23+
}
24+
25+
public function put(PDO $pdo)
26+
{
27+
return static::$channel->push($pdo);
28+
}
29+
}

0 commit comments

Comments
 (0)