diff --git a/README.md b/README.md index 7d91a83..5336811 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ docker compose exec -ti client bash # Get a Bash shell in the client container. * [support HTTP/1, HTTP/2, and WebSocket on same port](https://github.com/deminy/swoole-by-examples/blob/master/examples/servers/mixed-protocols-1.php) * support multiple protocols on same server * [DDoS protection](https://github.com/deminy/swoole-by-examples/blob/master/examples/servers/ddos-protection.php): How to protect your Swoole-based application server from DDoS attacks. + * [interruptible sleep](https://github.com/deminy/swoole-by-examples/blob/master/examples/servers/interruptible-sleep.php): This example shows how to set up a cronjob in a web server, and allow the cronjob to execute at a last time when the server is shutting down. * multiple ports listening * client-side programming * [HTTP/1 client](https://github.com/deminy/swoole-by-examples/blob/master/examples/clients/http1.php) diff --git a/docker-compose.yml b/docker-compose.yml index 48dcacf..a5c2f00 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: server: image: deminy/swoole-by-examples:server-5.1 environment: - AUTORELOAD_PROGRAMS: "ddos-protection http1 http1-integrated http2 keepalive mixed-protocols-1 pool-msgqueue pool-tcp-socket pool-unix-socket redis rock-paper-scissors tcp1 tcp2 udp websocket websocket-integrated" + 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" DISABLE_DEFAULT_SERVER: 1 ports: - 9801:9801 diff --git a/dockerfiles/server/rootfilesystem/etc/supervisor/service.d/interruptible-sleep.conf b/dockerfiles/server/rootfilesystem/etc/supervisor/service.d/interruptible-sleep.conf new file mode 100644 index 0000000..1066090 --- /dev/null +++ b/dockerfiles/server/rootfilesystem/etc/supervisor/service.d/interruptible-sleep.conf @@ -0,0 +1,12 @@ +[supervisord] +user = root + +[program:interruptible-sleep] +command = /var/www/servers/interruptible-sleep.php +user = root +autostart = true +autorestart = true +stdout_logfile=/proc/self/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/proc/self/fd/1 +stderr_logfile_maxbytes=0 diff --git a/examples/servers/interruptible-sleep.php b/examples/servers/interruptible-sleep.php new file mode 100755 index 0000000..a8e7243 --- /dev/null +++ b/examples/servers/interruptible-sleep.php @@ -0,0 +1,60 @@ +#!/usr/bin/env php +on('workerStart', function (Server $server, int $workerId) use ($exited) { + if ($workerId === 0) { + Coroutine::create(function () use ($exited) { + // Here we start the second cron job that makes an HTTP request every 19 seconds. + while (true) { + echo '[INTERRUPTIBLE-SLEEP] Simulating cronjob execution. (case 1)', PHP_EOL; + $exited->pop(19); + if ($exited->errCode === SWOOLE_CHANNEL_CLOSED) { + echo '[INTERRUPTIBLE-SLEEP] Simulating cronjob execution. (case 2)', PHP_EOL; + break; + } + } + echo '[INTERRUPTIBLE-SLEEP] The cronjob has exited.', PHP_EOL; + }); + } +}); +$server->on('workerExit', function (Server $server, int $workerId) use ($exited) { + echo "[INTERRUPTIBLE-SLEEP] Worker #{$workerId} is exiting.", PHP_EOL; + if ($workerId === 0) { + Coroutine::create(function () use ($exited) { + $exited->close(); + }); + } + echo "[INTERRUPTIBLE-SLEEP] Worker #{$workerId} has exited.", PHP_EOL; +}); +$server->on('request', function (Request $request, Response $response) { + $response->end('OK' . PHP_EOL); +}); + +$server->start();