-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reload the Swoole/Process code inside its callback on Swoole\Server->reload() #5505
Comments
I will take a look later. |
$proc = new Process(function ($process) {
// Business logic code here
},false, SOCK_DGRAM, true);
$id = $this->server->addProcess($proc);
$this->server->on('message', function($webSocketServer, $frame) use ($proc) {
// Before reload kill process
if ($webSocketServer->worker_id == 1) {
Process::kill($proc->pid, SIGTERM);
}
$reloadStatus = $webSocketServer->reload();
echo (($reloadStatus === true) ? PHP_EOL.'Code Reloaded'.PHP_EOL : PHP_EOL.'Code Not Reloaded').PHP_EOL;
// Other business logic
}); You need to add the user processes before executing |
Thanks, @NathanFreeman , for your help When the Swoole server is running, it creates user processes with new PIDs (Process IDs). We leverage this behavior to reload user processes by utilizing the BeforeReload event. During this event, we terminate the existing user processes, which forces Swoole to create new ones with fresh PIDs. As a result, any updated code is applied to the new processes. Important: Inside the process, if we write the business logic directly, it won't be reloaded. Instead, we must include the business logic from a separate file inside the process’s handler function. This ensures the logic gets reloaded when the new process is created. 1. Killing Processes in BeforeReload Event:In the BeforeReload event, we kill the current user processes so that Swoole can recreate them with new PIDs. We achieve this by iterating over the processes, killing them, and removing their PID files. <?php
$this->server->on('BeforeReload', function($server) {
// Iterate through the custom processes and terminate them
foreach($this->customProcessCallbacks as $key => $callback) {
$processPidFile = __DIR__ . '/process_pids/' . $key . '.pid';
// Check if the PID file exists and kill the process
if (file_exists($processPidFile)) {
$pid = shell_exec('cat ' . $processPidFile);
Process::kill((int) $pid, SIGTERM); // Terminate the process
// Remove the PID file
unlink($processPidFile);
}
}
});
?>
2. Creating the Process and Handling Business Logic:Here, we create the custom process and add it to the server. The key trick is to include the business logic file inside the handle() function. This ensures that when Swoole reloads the process, the new code will be picked up. <?php
$processCallback = new ProcessCallback();
// Add the process callback to an array that holds custom processes
$this->customProcessCallbacks['test_process'] = [$processCallback, 'handle'];
// Create the process and add it to the server
$testProcess = new Process($this->customProcessCallbacks['test_process'], false, SOCK_DGRAM, true);
$this->server->addProcess($testProcess);
$this->server->start(); // Start the server
?> 3. Process Callback Class:In the ProcessCallback class, we use the include statement to import the business logic from external files. This way, when Swoole creates a new process, the updated logic will be loaded. <?php
use Swoole\Timer;
class ProcessCallback
{
public function handle()
{
// Include the main business logic
include('path/to/business-logic-file.php');
// Set a timer to execute business logic periodically
Timer::tick(2000, function () {
include('path/to/timer-business-logic-file.php');
});
}
}
?> How It Works:1. Killing and Recreating Processes:In the BeforeReload event, we kill the existing user processes. 2. Reloading Business Logic:To ensure the latest business logic is applied, we use include inside the handle() function of the process. This will load the business logic from external files, ensuring it gets reloaded when a new process is created. |
|
You can send a signal to a custom process within the In the custom process, use After the custom process exits, the underlying system will restart a new instance of the custom process. |
1. What did you do? If possible, provide a simple script for reproducing the error.
Hi, I have a use case where I want to reload a custom process (Swoole\Process). According to the documentation, reload() has no effect on custom user processes. Is there any way to ensure that the code in the custom process is also reloaded when calling reload()?
I attempted the following approach (which didn’t work):
a) Create the Swoole\Process inside the onWorkerStart event.
b) Before calling $server->reload(), kill the custom process.
c) Create a new Swoole\Process when the onWorkerStart event is triggered again.
However, I discovered that we cannot create a Swoole\Process inside the onWorkerStart event. So, I tried another approach where I created the Swoole\Process in the main process. The idea was to store the process PID into Swoole\Coroutine\Table and fetch it before reload() to kill the process. But, as you know, reload() only affects worker and task processes not the main process.
Additionally, when I create a new process and try to retrieve its PID, I don’t receive it.
My question is: is there any method or technique that allows us to reload the code changes inside a custom Swoole\Process, added through
$server->addProcess($proc)
when calling reload(), and how can I reliably retrieve the PID of a newly created custom process in the parent process just as we get its id from $server->addProcess() ?2. What did you expect to see?
reload() function should also reload the code of the Swoole\Process
3. What did you see instead?
reload() function does not reload the code of Swoole\Process
4. What version of Swoole are you using (show your
php --ri swoole
)?5. What is your machine environment used (show your
uname -a
&php -v
&gcc -v
) ?The text was updated successfully, but these errors were encountered: