Smooth Restart Principle

What is Smooth Restart?

Smooth restart differs from a regular restart; it allows services (typically referring to short link services) to be restarted without affecting users, in order to reload the PHP program and complete business code updates.

Smooth restart is generally applied during business updates or version releases, helping to avoid temporary service unavailability caused by code deployment and service restarts.

Note
Windows systems do not support reload.

Note
For long connection services (like websocket), connections will be dropped during the process's smooth restart. The solution is to use an architecture similar to gatewayWorker, where a group of processes is dedicated to maintaining connections, and the reloadable attribute of this group of processes is set to false. The business logic starts another group of worker processes to handle the workload, with the gateway and worker processes communicating with each other via TCP. When business changes are needed, only the worker processes need to be restarted.

Limitations

Note: Only files loaded in on{...} callbacks will automatically update after a smooth restart. Files loaded directly in the startup script or hard-coded code will not automatically update upon running reload.

The following code will not update after reload

$worker = new Worker('http://0.0.0.0:1234');
$worker->onMessage = function($connection, $request) {
    $connection->send('hi'); // Hard-coded code does not support hot updates
};
$worker = new Worker('http://0.0.0.0:1234');
require_once __DIR__ . '/your/path/MessageHandler.php'; // Files loaded directly in the startup script do not support hot updates
$messageHandler = new MessageHandler();
$worker->onMessage = [$messageHandler, 'onMessage']; // Assuming MessageHandler class has an onMessage method

The following code will automatically update after reload

$worker = new Worker('http://0.0.0.0:1234');
$worker->onWorkerStart = function($worker) { // onWorkerStart is a callback triggered after the process starts
    require_once __DIR__ . '/your/path/MessageHandler.php'; // Files loaded after the process starts support hot updates
    $messageHandler = new MessageHandler();
    $worker->onMessage = [$messageHandler, 'onMessage'];
};

After modifying MessageHandler.php, running php start.php reload will reload MessageHandler.php into memory, achieving the effect of updating business logic.

Tip
The above code uses require_once for demonstration purposes. If your project supports PSR-4 autoloading, there is no need to call require_once.

Smooth Restart Principle

Workerman is composed of a master process and worker processes. The master process is responsible for monitoring the worker processes, while the worker processes are in charge of receiving client connections and the request data sent over these connections, processing them accordingly, and returning data to the client. When business code is updated, we only need to update the worker processes to achieve code updates.

When the Workerman master process receives a smooth restart signal, it sends a safe exit signal to one of the worker processes (allowing the corresponding process to complete the current request before it exits). Once this process exits, the master process will recreate a new worker process (which loads the new PHP code), and then the master process sends a stop command to another old process, effectively restarting the processes one by one until all old processes are replaced.

We see that smooth restart is essentially about having old business processes exit one by one and creating new processes in turn. To avoid affecting users during a smooth restart, it is essential that processes do not retain user-related state information, meaning that business processes should ideally be stateless to prevent information loss due to process exit.