Files
kiri-http-server/Abstracts/ReloadWorkers.php
T
2026-07-10 15:57:44 +08:00

116 lines
2.4 KiB
PHP

<?php
namespace Kiri\Server\Abstracts;
use Swoole\Process;
trait ReloadWorkers
{
private static ?int $cachedMasterPid = null;
/**
* @return void
*/
private function reloadWorkers(): bool
{
$pid = $this->getMasterPid();
if ($pid === null) {
return false;
}
return Process::kill($pid, SIGUSR1);
}
private function getMasterPid(): ?int
{
if (self::$cachedMasterPid !== null && $this->isCachedMasterPid(self::$cachedMasterPid)) {
return self::$cachedMasterPid;
}
self::$cachedMasterPid = null;
$processes = $this->listProcesses();
$candidates = [];
$pidFile = function_exists('storage') ? storage('.swoole.pid') : '';
if (is_file($pidFile)) {
$candidates[] = (int)trim((string)file_get_contents($pidFile));
}
foreach ($processes as $process) {
if ($this->isMasterProcessCommand($process['command'])) {
$candidates[] = (int)$process['pid'];
}
}
foreach ($candidates
|> array_filter(...)
|> array_unique(...)
|> array_values(...) as $pid) {
if ($this->isProcessAlive($pid) && $this->isMasterPid($pid, $processes)) {
self::$cachedMasterPid = $pid;
return $pid;
}
}
return null;
}
private function isCachedMasterPid(int $pid): bool
{
if (!$this->isProcessAlive($pid)) {
return false;
}
$command = $this->readProcessCommand($pid);
return $command !== '' && $this->isMasterProcessCommand($command) && $this->isSameAppProcess($pid);
}
private function readProcessCommand(int $pid): string
{
$cmdline = @file_get_contents('/proc/' . $pid . '/cmdline');
if (is_string($cmdline) && $cmdline !== '') {
return trim(str_replace("\0", ' ', $cmdline));
}
return '';
}
private function isMasterPid(int $pid, array $processes): bool
{
foreach ($processes as $process) {
if ((int)$process['pid'] === $pid) {
return $this->isMasterProcessCommand($process['command']) && $this->isSameAppProcess($pid);
}
}
return false;
}
private function listProcesses(): array
{
$lines = [];
exec('ps -eo pid=,ppid=,args=', $lines);
$processes = [];
foreach ($lines as $line) {
$line = trim($line);
if ($line === '') {
continue;
}
$parts = preg_split('/\s+/', $line, 3);
if (count($parts) < 3) {
continue;
}
$processes[] = [
'pid' => (int)$parts[0],
'ppid' => (int)$parts[1],
'command' => $parts[2],
];
}
return $processes;
}
}