phasync
Swerve / onShutdown

Method

Swerve::onShutdown

Run $callback when this worker must now close its connections: for an upgraded connection, to say goodbye in its protocol and end it.

Description#

public static Swerve::onShutdown(
    Closure $callback
): void

That is when a shutdown or a reload begins to drain the worker, and, for a worker replaced by a recycle (which keeps its upgraded connections for up to --linger seconds), at the end of that time. The callback runs in a coroutine of its own, so a slow one delays no other and one that throws, which is logged, stops none; it runs at once when that moment has passed already. Its waits get the worker's WorkerStoppingException too: write a goodbye inside phasync::shielded().

The callback belongs to the Scope that registered it (a request's, or outside any request the root scope), runs in it, and goes when that request ends, without running: swerve holds no reference to the request. phasync collects the cycles half a second after a coroutine ends, so what the callback holds is freed shortly after.

Parameters#

$callback Closure
Called without arguments; its return value is ignored

Errors / Exceptions#

ExceptionWhen
LogicExceptionOutside a coroutine

Examples#

Example 1Close a WebSocket with a reason when the server stops
use Swerve\ClientRequest;
use Swerve\RequestHandler;
use Swerve\Swerve;
use Swerve\WebSocket;

$app = new RequestHandler(function (ClientRequest $request) {
    WebSocket::from($request, function (WebSocket $ws) {
        // When the worker must close its connections: say why, in the protocol
        Swerve::onShutdown(fn () => phasync::shielded(fn () => $ws->end(1001, 'server restarting')));

        $ws->send('welcome');
        foreach ($ws as $message) {
            $ws->send($message);
        }
    });
});

if (debug_backtrace()) {
    return $app;   // swerve loads this file: it is the application's swerve.php
}

// Run directly: serve the application with swerve, and talk to it as a browser would
require __DIR__ . '/../serve.php';
websocket(__FILE__, '/live', [], stop: SIGTERM);   // swerve is stopped after the welcome
Output
HTTP/1.1 101 Switching Protocols
upgrade: websocket
connection: Upgrade
sec-websocket-accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Server: Swerve

< welcome
< close 1001 server restarting
Example 2
YourProtocol::from($request, function (YourProtocol $conn) {
    Swerve::onShutdown(fn () => phasync::shielded(fn () => $conn->end('restarting')));
    foreach ($conn as $message) {
        $conn->send(handle($message));
    }
});

See also#