2022-03-15 18:05:33 +08:00
|
|
|
|
<?php
|
2021-01-20 16:11:04 +08:00
|
|
|
|
|
2022-03-15 18:05:33 +08:00
|
|
|
|
declare(strict_types=1);
|
2021-01-20 16:11:04 +08:00
|
|
|
|
|
2022-08-01 16:31:54 +08:00
|
|
|
|
namespace ZM\Process;
|
2021-01-20 16:11:04 +08:00
|
|
|
|
|
2022-05-14 23:43:15 +08:00
|
|
|
|
use ZM\Exception\ZMKnownException;
|
2022-08-01 16:31:54 +08:00
|
|
|
|
use ZM\Store\FileSystem;
|
2021-03-24 23:34:46 +08:00
|
|
|
|
|
2022-08-01 16:31:54 +08:00
|
|
|
|
class ProcessStateManager
|
2021-01-20 16:11:04 +08:00
|
|
|
|
{
|
2022-08-22 20:54:14 +08:00
|
|
|
|
public static array $process_mode = [];
|
2022-05-14 23:43:15 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @throws ZMKnownException
|
|
|
|
|
|
* @internal
|
|
|
|
|
|
*/
|
2022-12-19 20:22:47 +08:00
|
|
|
|
public static function removeProcessState(int $type, int|string $id_or_name = null)
|
2022-05-14 23:43:15 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch ($type) {
|
|
|
|
|
|
case ZM_PROCESS_MASTER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/master.json');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
if (file_exists($file)) {
|
|
|
|
|
|
unlink($file);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_MANAGER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/manager.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
if (file_exists($file)) {
|
|
|
|
|
|
unlink($file);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_WORKER:
|
|
|
|
|
|
if (!is_int($id_or_name)) {
|
|
|
|
|
|
throw new ZMKnownException('E99999', 'worker_id必须为整数');
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/worker.' . $id_or_name . '.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
if (file_exists($file)) {
|
|
|
|
|
|
unlink($file);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_USER:
|
|
|
|
|
|
if (!is_string($id_or_name)) {
|
|
|
|
|
|
throw new ZMKnownException('E99999', 'process_name必须为字符串');
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/user.' . $id_or_name . '.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
if (file_exists($file)) {
|
|
|
|
|
|
unlink($file);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_TASKWORKER:
|
|
|
|
|
|
if (!is_int($id_or_name)) {
|
|
|
|
|
|
throw new ZMKnownException('E99999', 'worker_id必须为整数');
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/taskworker.' . $id_or_name . '.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
if (file_exists($file)) {
|
|
|
|
|
|
unlink($file);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 用于框架内部获取多进程运行状态的函数
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return false|int|mixed
|
2022-09-09 18:59:46 +08:00
|
|
|
|
* @throws ZMKnownException
|
2022-05-14 23:43:15 +08:00
|
|
|
|
* @internal
|
|
|
|
|
|
*/
|
2022-12-19 20:22:47 +08:00
|
|
|
|
public static function getProcessState(int $type, mixed $id_or_name = null)
|
2022-05-14 23:43:15 +08:00
|
|
|
|
{
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = ZM_STATE_DIR;
|
2022-05-14 23:43:15 +08:00
|
|
|
|
switch ($type) {
|
|
|
|
|
|
case ZM_PROCESS_MASTER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
if (!file_exists(zm_dir($file . '/master.json'))) {
|
2022-05-14 23:43:15 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$json = json_decode(file_get_contents(zm_dir($file . '/master.json')), true);
|
2022-12-19 20:22:47 +08:00
|
|
|
|
return $json ?? false;
|
2022-05-14 23:43:15 +08:00
|
|
|
|
case ZM_PROCESS_MANAGER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
if (!file_exists(zm_dir($file . '/manager.pid'))) {
|
2022-05-14 23:43:15 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
return intval(file_get_contents(zm_dir($file . '/manager.pid')));
|
2022-05-14 23:43:15 +08:00
|
|
|
|
case ZM_PROCESS_WORKER:
|
|
|
|
|
|
if (!is_int($id_or_name)) {
|
|
|
|
|
|
throw new ZMKnownException('E99999', 'worker_id必须为整数');
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
if (!file_exists(zm_dir($file . '/worker.' . $id_or_name . '.pid'))) {
|
2022-05-14 23:43:15 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
return intval(file_get_contents(zm_dir($file . '/worker.' . $id_or_name . '.pid')));
|
2022-05-14 23:43:15 +08:00
|
|
|
|
case ZM_PROCESS_USER:
|
|
|
|
|
|
if (!is_string($id_or_name)) {
|
|
|
|
|
|
throw new ZMKnownException('E99999', 'process_name必须为字符串');
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
if (!file_exists(zm_dir($file . '/user.' . $id_or_name . '.pid'))) {
|
2022-05-14 23:43:15 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
return intval(file_get_contents(zm_dir($file . '/user.' . $id_or_name . '.pid')));
|
2022-05-14 23:43:15 +08:00
|
|
|
|
case ZM_PROCESS_TASKWORKER:
|
|
|
|
|
|
if (!is_int($id_or_name)) {
|
|
|
|
|
|
throw new ZMKnownException('E99999', 'worker_id必须为整数');
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
if (!file_exists(zm_dir($file . '/taskworker.' . $id_or_name . '.pid'))) {
|
2022-05-14 23:43:15 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2022-09-26 22:44:41 +08:00
|
|
|
|
return intval(file_get_contents(zm_dir($file . '/taskworker.' . $id_or_name . '.pid')));
|
2022-05-14 23:43:15 +08:00
|
|
|
|
default:
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将各进程的pid写入文件,以备后续崩溃及僵尸进程处理使用
|
|
|
|
|
|
*
|
|
|
|
|
|
* @internal
|
|
|
|
|
|
*/
|
2022-12-19 20:22:47 +08:00
|
|
|
|
public static function saveProcessState(int $type, int|string $pid, array $data = [])
|
2022-05-14 23:43:15 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch ($type) {
|
|
|
|
|
|
case ZM_PROCESS_MASTER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/master.json');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
$json = [
|
|
|
|
|
|
'pid' => intval($pid),
|
|
|
|
|
|
'stdout' => $data['stdout'],
|
|
|
|
|
|
'daemon' => $data['daemon'],
|
|
|
|
|
|
];
|
|
|
|
|
|
file_put_contents($file, json_encode($json, JSON_UNESCAPED_UNICODE));
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_MANAGER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/manager.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
file_put_contents($file, strval($pid));
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_WORKER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/worker.' . $data['worker_id'] . '.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
file_put_contents($file, strval($pid));
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_USER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/user.' . $data['process_name'] . '.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
file_put_contents($file, strval($pid));
|
|
|
|
|
|
return;
|
|
|
|
|
|
case ZM_PROCESS_TASKWORKER:
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$file = zm_dir(ZM_STATE_DIR . '/taskworker.' . $data['worker_id'] . '.pid');
|
2022-05-14 23:43:15 +08:00
|
|
|
|
file_put_contents($file, strval($pid));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static function isStateEmpty(): bool
|
|
|
|
|
|
{
|
2022-09-26 22:44:41 +08:00
|
|
|
|
$ls = FileSystem::scanDirFiles(ZM_STATE_DIR, false, true);
|
2022-05-14 23:43:15 +08:00
|
|
|
|
return empty($ls);
|
|
|
|
|
|
}
|
2022-03-15 18:05:33 +08:00
|
|
|
|
}
|