Skip to content

Commit 0dda90b

Browse files
committed
add new example APCu Caching
Signed-off-by: Demin Yin <deminy@deminy.net>
1 parent d392e2b commit 0dda90b

File tree

7 files changed

+82
-5
lines changed

7 files changed

+82
-5
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ docker compose exec -ti client bash # Get a Bash shell in the client container.
136136
* [UDP client](https://github.com/deminy/swoole-by-examples/blob/master/examples/clients/udp.php)
137137
* [PostgreSQL client](https://github.com/deminy/swoole-by-examples/blob/master/examples/clients/postgresql.php)
138138
* miscellaneous topics
139+
* data management in Swoole: globals, persistence, and caching
140+
* [APCu Caching]: APCu caching in Swoole works the same way as in other PHP CLI applications. This example explains it in details.
139141
* atomic counters
140142
* [implement atomic counters using unsigned 32-bit integers](https://github.com/deminy/swoole-by-examples/blob/master/examples/misc/atomic-counter-unsigned-32-bit.php)
141143
* [implement atomic counters using signed 64-bit integers](https://github.com/deminy/swoole-by-examples/blob/master/examples/misc/atomic-counter-signed-64-bit.php)
@@ -144,3 +146,5 @@ docker compose exec -ti client bash # Get a Bash shell in the client container.
144146
* process pool
145147
* pool creation and inter-process communication: Please check previous section `resource pooling` for details.
146148
* detach processes from a process pool
149+
150+
[APCu Caching]: https://github.com/deminy/swoole-by-examples/blob/master/examples/servers/apcu-caching.php

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ services:
44
server:
55
image: deminy/swoole-by-examples:server-5.1
66
environment:
7-
AUTORELOAD_PROGRAMS: "ddos-protection http1 http1-integrated http2 interruptible-sleep keepalive mixed-protocols-1 pool-msgqueue pool-tcp-socket pool-unix-socket redis rock-paper-scissors tcp1 tcp2 udp websocket websocket-integrated"
7+
AUTORELOAD_PROGRAMS: "apcu-caching ddos-protection http1 http1-integrated http2 interruptible-sleep keepalive mixed-protocols-1 pool-msgqueue pool-tcp-socket pool-unix-socket redis rock-paper-scissors tcp1 tcp2 udp websocket websocket-integrated"
88
DISABLE_DEFAULT_SERVER: 1
99
ports:
1010
- 9801:9801

dockerfiles/client/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# This Dockerfile is to build Docker image "deminy/swoole-by-examples:client".
1+
# This Dockerfile is to build Docker image "deminy/swoole-by-examples:client-5.1".
22
# @see https://hub.docker.com/r/deminy/swoole-by-examples
33
FROM phpswoole/swoole:5.1-php8.2
44

dockerfiles/server/Dockerfile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1-
# This Dockerfile is to build Docker image "deminy/swoole-by-examples:server".
1+
# This Dockerfile is to build Docker image "deminy/swoole-by-examples:server-5.1".
22
# @see https://hub.docker.com/r/deminy/swoole-by-examples
33
FROM phpswoole/swoole:5.1-php8.2
44

55
COPY ./rootfilesystem /
66

7-
# The System V messages support is to run some example in script "./examples/pool/process-pool/client.php".
7+
# 1. The System V messages support is to run the example from script "./examples/pool/process-pool/client.php".
8+
# 2. The APCu extension is to run the example from script "./examples/servers/apcu-caching.php".
89
RUN \
910
set -ex && \
1011
docker-php-ext-install sysvmsg && \
12+
pecl channel-update pecl && \
13+
pecl install apcu-stable && \
14+
docker-php-ext-enable apcu && \
15+
echo "apc.enable_cli=1" >> $(php-config --ini-dir)/docker-php-ext-apcu.ini && \
1116
apt-get update && \
1217
apt-get install -y net-tools watch --no-install-recommends && \
1318
rm -rf /var/lib/apt/lists/*
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[supervisord]
2+
user = root
3+
4+
[program:apcu-caching]
5+
command = /var/www/servers/apcu-caching.php
6+
user = root
7+
autostart = true
8+
autorestart = true
9+
stdout_logfile=/proc/self/fd/1
10+
stdout_logfile_maxbytes=0
11+
stderr_logfile=/proc/self/fd/1
12+
stderr_logfile_maxbytes=0

examples/pool/process-pool/pool-standalone.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
$counter = new Atomic(0);
2222

2323
$pool->on('workerStart', function (Pool $pool, int $workerId) use ($counter) {
24-
# For standalone process pool, business logic should be implemented inside this "workerStart" callback.
24+
// For standalone process pool, business logic should be implemented inside this "workerStart" callback.
2525
echo "Process #{$workerId} (process ID in the OS: {$pool->getProcess()->pid}) started.", PHP_EOL; // @phpstan-ignore property.nonObject
2626
$counter->add(1);
2727
});

examples/servers/apcu-caching.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
declare(strict_types=1);
5+
6+
/**
7+
* In this example we use APCu to count number of HTTP requests processed by each worker process in Swoole. From this
8+
* example, we can see that APCu caching in Swoole works the same way as in other PHP CLI applications, even when
9+
* multiple coroutines and multiple processes are involved.
10+
*
11+
* Here is how to run this example:
12+
* 1. First, let's make 499 HTTP requests to the server concurrently:
13+
* docker compose exec -t client ab -n 499 -c 499 http://server:9513/
14+
* With the above command, we make 499 HTTP requests to the server concurrently. The server uses APCu to store the
15+
* number of HTTP requests processed by each worker process.
16+
* 2. Next, let's check the summary of all counters by making another HTTP request to the server:
17+
* docker compose exec -t client curl http://server:9513/summary
18+
* The server has 3 worker processes to process these requests. Hopefully we can see that each worker process
19+
* processes different number of HTTP requests.
20+
*/
21+
22+
use Swoole\Constant;
23+
use Swoole\Http\Request;
24+
use Swoole\Http\Response;
25+
use Swoole\Http\Server;
26+
27+
apcu_clear_cache(); // Clear APCu caches.
28+
29+
$server = new Server('0.0.0.0', 9513);
30+
$server->set(
31+
[
32+
Constant::OPTION_WORKER_NUM => 3, // The number of worker processes to process HTTP requests.
33+
]
34+
);
35+
36+
$server->on(
37+
'request',
38+
function (Request $request, Response $response) use ($server): void {
39+
if ($request->server['request_uri'] === '/summary') { // Show summary of all counters.
40+
$output = '';
41+
foreach (apcu_cache_info()['cache_list'] as $item) { // @phpstan-ignore foreach.nonIterable
42+
$output .= "{$item['info']}: " . apcu_fetch($item['info']) . PHP_EOL; // @phpstan-ignore-line
43+
}
44+
// The output will be like:
45+
// counter_0: 46
46+
// counter_1: 16
47+
// counter_2: 437
48+
$response->end($output);
49+
} else { // Increase a counter.
50+
apcu_inc("counter_{$server->worker_id}");
51+
$response->end('OK' . PHP_EOL);
52+
}
53+
}
54+
);
55+
56+
$server->start();

0 commit comments

Comments
 (0)