add state and ctrl+C support for windows

This commit is contained in:
crazywhalecc
2022-09-26 22:44:41 +08:00
parent cf3f09600b
commit a4f992b9e5
14 changed files with 143 additions and 108 deletions

View File

@@ -2,21 +2,23 @@
declare(strict_types=1); declare(strict_types=1);
$plugin = new \ZM\Plugin\InstantPlugin(__DIR__);
/* /*
return function () { * 发送 "测试 123",回复 "你好123"
$plugin = new \ZM\Plugin\InstantPlugin(__DIR__); */
$cmd1 = BotCommand::make('test', '测试')->withArgument('arg1')->on(fn () => '你好,{{arg1}}');
$cmd = \ZM\Annotation\OneBot\BotCommand::make(name: 'test', match: '测试')->withArgument(name: 'arg1')->withMethod(function () { /*
ctx()->reply('test ok'); * 浏览器访问 http://ip:port/index233返回内容
}); */
$event = BotEvent::make(type: 'message')->withMethod(function () { $route1 = Route::make('/index233')->on(fn () => '<h1>Hello world</h1>');
});
$plugin->addBotEvent($event);
$plugin->addBotCommand($cmd);
$plugin->registerEvent(HttpRequestEvent::getName(), function (HttpRequestEvent $event) { $plugin->addBotCommand($cmd1);
$event->withResponse(\OneBot\Http\HttpFactory::getInstance()->createResponse(503)); $plugin->addHttpRoute($route1);
});
return $plugin; return [
}; 'plugin-name' => 'pasd',
*/ 'version' => '1.0.0',
'plugin' => $plugin,
];

View File

@@ -37,6 +37,16 @@ define('WORKING_DIR', getcwd());
/* 定义源码根目录,如果是 Phar 打包框架运行的话,就是 Phar 文件本身 */ /* 定义源码根目录,如果是 Phar 打包框架运行的话,就是 Phar 文件本身 */
define('SOURCE_ROOT_DIR', Phar::running() !== '' ? Phar::running() : WORKING_DIR); define('SOURCE_ROOT_DIR', Phar::running() !== '' ? Phar::running() : WORKING_DIR);
if (DIRECTORY_SEPARATOR === '\\') {
define('TMP_DIR', 'C:\\Windows\\Temp');
} elseif (!empty(getenv('TMPDIR'))) {
define('TMP_DIR', getenv('TMPDIR'));
} elseif (is_writable('/tmp')) {
define('TMP_DIR', '/tmp');
} else {
define('TMP_DIR', getcwd() . '/.zm-tmp');
}
/* 定义启动模式,这里指的是框架本身的源码目录是通过 composer 加入 vendor 加载的还是直接放到 src 目录加载的,前者为 1后者为 0 */ /* 定义启动模式,这里指的是框架本身的源码目录是通过 composer 加入 vendor 加载的还是直接放到 src 目录加载的,前者为 1后者为 0 */
define('LOAD_MODE', is_dir(zm_dir(SOURCE_ROOT_DIR . '/src/ZM')) ? 0 : 1); define('LOAD_MODE', is_dir(zm_dir(SOURCE_ROOT_DIR . '/src/ZM')) ? 0 : 1);
@@ -47,10 +57,8 @@ if (Phar::running() !== '') {
define('FRAMEWORK_ROOT_DIR', realpath(zm_dir(__DIR__ . '/../../'))); define('FRAMEWORK_ROOT_DIR', realpath(zm_dir(__DIR__ . '/../../')));
} }
/* 定义用于存放框架运行状态的目录Windows 可用) */ /* 定义用于存放框架运行状态的目录Windows 可用) */
if (DIRECTORY_SEPARATOR !== '\\') { define('ZM_STATE_DIR', TMP_DIR . '/.zm_' . sha1(FRAMEWORK_ROOT_DIR));
define('ZM_PID_DIR', '/tmp/.zm_' . sha1(FRAMEWORK_ROOT_DIR));
}
/* 对 global.php 在 Windows 下的兼容性考虑,因为 Windows 或者无 Swoole 环境时候无法运行 */ /* 对 global.php 在 Windows 下的兼容性考虑,因为 Windows 或者无 Swoole 环境时候无法运行 */
!defined('SWOOLE_BASE') && define('SWOOLE_BASE', 1) && define('SWOOLE_PROCESS', 2); !defined('SWOOLE_BASE') && define('SWOOLE_BASE', 1) && define('SWOOLE_PROCESS', 2);

View File

@@ -59,8 +59,7 @@ class BotCommand extends AnnotationBase implements Level
/** @var int */ /** @var int */
public $level = 20; public $level = 20;
/** @var array */ private array $arguments = [];
private $arguments = [];
public function __construct( public function __construct(
$name = '', $name = '',

View File

@@ -19,23 +19,17 @@ use ZM\Annotation\AnnotationBase;
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class BotEvent extends AnnotationBase class BotEvent extends AnnotationBase
{ {
/** @var null|string */ public ?string $type;
public $type;
/** @var null|string */ public ?string $detail_type;
public $detail_type;
/** @var null|string */ public ?string $impl;
public $impl;
/** @var null|string */ public ?string $platform;
public $platform;
/** @var null|string */ public ?string $self_id;
public $self_id;
/** @var null|string */ public ?string $sub_type;
public $sub_type;
public function __construct( public function __construct(
?string $type = null, ?string $type = null,

View File

@@ -22,45 +22,23 @@ use ZM\Exception\ZMKnownException;
class CommandArgument extends AnnotationBase implements ErgodicAnnotation class CommandArgument extends AnnotationBase implements ErgodicAnnotation
{ {
/** /**
* @var string
* @Required() * @Required()
*/ */
public $name; public string $name;
/** public string $description = '';
* @var string
*/
public $description = '';
/** public string $type = 'string';
* @var string
*/
public $type = 'string';
/** public bool $required = false;
* @var bool
*/
public $required = false;
/** public string $prompt = '';
* @var string
*/
public $prompt = '';
/** public string $default = '';
* @var string
*/
public $default = '';
/** public int $timeout = 60;
* @var int
*/
public $timeout = 60;
/** public int $error_prompt_policy = 1;
* @var int
*/
public $error_prompt_policy = 1;
/** /**
* @param string $name 参数名称(可以是中文) * @param string $name 参数名称(可以是中文)

View File

@@ -26,7 +26,7 @@ class ServerStopCommand extends ServerCommand
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
if ($input->getOption('force') !== false) { if ($input->getOption('force') !== false) {
$file_path = ZM_PID_DIR; $file_path = ZM_STATE_DIR;
$list = FileSystem::scanDirFiles($file_path, false, true); $list = FileSystem::scanDirFiles($file_path, false, true);
foreach ($list as $file) { foreach ($list as $file) {
$name = explode('.', $file); $name = explode('.', $file);

View File

@@ -51,10 +51,10 @@ class MasterEventListener
public function onMasterStop() public function onMasterStop()
{ {
if (extension_loaded('posix')) { if (extension_loaded('posix')) {
logger()->debug('正在关闭 Master 进程pid=' . posix_getpid()); logger()->debug('正在关闭 Master 进程pid=' . getmypid());
ProcessStateManager::removeProcessState(ZM_PROCESS_MASTER); ProcessStateManager::removeProcessState(ZM_PROCESS_MASTER);
if (FileSystem::scanDirFiles(ZM_PID_DIR) == []) { if (FileSystem::scanDirFiles(ZM_STATE_DIR) == []) {
rmdir(ZM_PID_DIR); rmdir(ZM_STATE_DIR);
} }
} }
} }

View File

@@ -113,6 +113,22 @@ class SignalListener
} }
} }
public function signalWindowsCtrlC()
{
if (self::$manager_kill_time > 0) {
if (self::$manager_kill_time >= 5) {
exit(0);
}
echo "\r";
logger()->notice('请再按 {count} 次 Ctrl+C 以强制杀死进程', ['count' => 5 - self::$manager_kill_time]);
return;
}
++self::$manager_kill_time;
if (self::$manager_kill_time === 1) {
Framework::getInstance()->stop();
}
}
/** /**
* 按5次Ctrl+C后强行杀死框架的处理函数 * 按5次Ctrl+C后强行杀死框架的处理函数
*/ */
@@ -120,7 +136,7 @@ class SignalListener
{ {
if (self::$manager_kill_time > 0) { if (self::$manager_kill_time > 0) {
if (self::$manager_kill_time >= 5) { if (self::$manager_kill_time >= 5) {
$file_path = ZM_PID_DIR; $file_path = ZM_STATE_DIR;
$flist = FileSystem::scanDirFiles($file_path, false, true); $flist = FileSystem::scanDirFiles($file_path, false, true);
foreach ($flist as $file) { foreach ($flist as $file) {
$name = explode('.', $file); $name = explode('.', $file);

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace ZM\Event\Listener;
use OneBot\Driver\Event\WebSocket\WebSocketOpenEvent;
use OneBot\Http\HttpFactory;
use OneBot\Util\Singleton;
use ZM\Container\ContainerServicesProvider;
class WSEventListener
{
use Singleton;
public function onWebSocketOpen(WebSocketOpenEvent $event)
{
// 注册容器
resolve(ContainerServicesProvider::class)->registerServices('connection');
// 判断是不是 OneBot 12 反向 WS 连进来的,通过 Sec-WebSocket-Protocol 头
$line = explode('.', $event->getRequest()->getHeaderLine('Sec-WebSocket-Protocol'), 2);
if ($line[0] === '12') {
// 是 OneBot 12 标准的,准许接入,进行鉴权
$request = $event->getRequest();
if (($stored_token = $event->getSocketConfig()['access_token'] ?? '') !== '') {
$token = $request->getHeaderLine('Authorization');
$token = explode('Bearer ', $token);
if (!isset($token[1]) || $token[1] !== $stored_token) { // 没有 token鉴权失败
$event->withResponse(HttpFactory::getInstance()->createResponse(401, 'Unauthorized'));
return;
}
}
// 这里下面为连接准入,允许接入反向 WSTODO
}
}
}

View File

@@ -37,6 +37,13 @@ class WorkerEventListener
if (!Framework::getInstance()->getArgv()['disable-safe-exit'] && PHP_OS_FAMILY !== 'Windows') { if (!Framework::getInstance()->getArgv()['disable-safe-exit'] && PHP_OS_FAMILY !== 'Windows') {
SignalListener::getInstance()->signalWorker(); SignalListener::getInstance()->signalWorker();
} }
// Windows 环境下,为了监听 Ctrl+C只能开启终端输入
if (PHP_OS_FAMILY === 'Windows') {
sapi_windows_set_ctrl_handler([SignalListener::getInstance(), 'signalWindowsCtrlC']);
Framework::getInstance()->getDriver()->getEventLoop()->addReadEvent(STDIN, function ($x) {});
}
logger()->debug('Worker #' . ProcessManager::getProcessId() . ' started'); logger()->debug('Worker #' . ProcessManager::getProcessId() . ' started');
// 设置 Worker 进程的状态和 ID 等信息 // 设置 Worker 进程的状态和 ID 等信息
@@ -44,8 +51,8 @@ class WorkerEventListener
/* @phpstan-ignore-next-line */ /* @phpstan-ignore-next-line */
$server = Framework::getInstance()->getDriver()->getSwooleServer(); $server = Framework::getInstance()->getDriver()->getSwooleServer();
ProcessStateManager::saveProcessState(ZM_PROCESS_WORKER, $server->worker_pid, ['worker_id' => $server->worker_id]); ProcessStateManager::saveProcessState(ZM_PROCESS_WORKER, $server->worker_pid, ['worker_id' => $server->worker_id]);
} elseif ($name === 'workerman' && DIRECTORY_SEPARATOR !== '\\' && extension_loaded('posix')) { } elseif ($name === 'workerman') {
ProcessStateManager::saveProcessState(ZM_PROCESS_WORKER, posix_getpid(), ['worker_id' => ProcessManager::getProcessId()]); ProcessStateManager::saveProcessState(ZM_PROCESS_WORKER, getmypid(), ['worker_id' => ProcessManager::getProcessId()]);
} }
// 打印进程ID // 打印进程ID

View File

@@ -12,6 +12,7 @@ use OneBot\Driver\Event\Process\ManagerStartEvent;
use OneBot\Driver\Event\Process\ManagerStopEvent; use OneBot\Driver\Event\Process\ManagerStopEvent;
use OneBot\Driver\Event\Process\WorkerStartEvent; use OneBot\Driver\Event\Process\WorkerStartEvent;
use OneBot\Driver\Event\Process\WorkerStopEvent; use OneBot\Driver\Event\Process\WorkerStopEvent;
use OneBot\Driver\Event\WebSocket\WebSocketOpenEvent;
use OneBot\Driver\Interfaces\DriverInitPolicy; use OneBot\Driver\Interfaces\DriverInitPolicy;
use OneBot\Driver\Swoole\SwooleDriver; use OneBot\Driver\Swoole\SwooleDriver;
use OneBot\Driver\Workerman\Worker; use OneBot\Driver\Workerman\Worker;
@@ -25,6 +26,7 @@ use ZM\Event\Listener\HttpEventListener;
use ZM\Event\Listener\ManagerEventListener; use ZM\Event\Listener\ManagerEventListener;
use ZM\Event\Listener\MasterEventListener; use ZM\Event\Listener\MasterEventListener;
use ZM\Event\Listener\WorkerEventListener; use ZM\Event\Listener\WorkerEventListener;
use ZM\Event\Listener\WSEventListener;
use ZM\Exception\ConfigException; use ZM\Exception\ConfigException;
use ZM\Exception\InitException; use ZM\Exception\InitException;
use ZM\Exception\ZMKnownException; use ZM\Exception\ZMKnownException;
@@ -292,14 +294,6 @@ class Framework
ob_event_provider()->addEventListener(WorkerStartEvent::getName(), [WorkerEventListener::getInstance(), 'onWorkerStart999'], 999); ob_event_provider()->addEventListener(WorkerStartEvent::getName(), [WorkerEventListener::getInstance(), 'onWorkerStart999'], 999);
ob_event_provider()->addEventListener(WorkerStopEvent::getName(), [WorkerEventListener::getInstance(), 'onWorkerStop999'], 999); ob_event_provider()->addEventListener(WorkerStopEvent::getName(), [WorkerEventListener::getInstance(), 'onWorkerStop999'], 999);
// Http 事件 // Http 事件
ob_event_provider()->addEventListener(HttpRequestEvent::getName(), function () {
global $starttime;
$starttime = microtime(true);
}, 1000);
ob_event_provider()->addEventListener(HttpRequestEvent::getName(), function () {
global $starttime;
logger()->error('Finally used ' . round((microtime(true) - $starttime) * 1000, 4) . ' ms');
}, 0);
ob_event_provider()->addEventListener(HttpRequestEvent::getName(), [HttpEventListener::getInstance(), 'onRequest999'], 999); ob_event_provider()->addEventListener(HttpRequestEvent::getName(), [HttpEventListener::getInstance(), 'onRequest999'], 999);
ob_event_provider()->addEventListener(HttpRequestEvent::getName(), [HttpEventListener::getInstance(), 'onRequest1'], 1); ob_event_provider()->addEventListener(HttpRequestEvent::getName(), [HttpEventListener::getInstance(), 'onRequest1'], 1);
// manager 事件 // manager 事件
@@ -307,10 +301,12 @@ class Framework
ob_event_provider()->addEventListener(ManagerStopEvent::getName(), [ManagerEventListener::getInstance(), 'onManagerStop'], 999); ob_event_provider()->addEventListener(ManagerStopEvent::getName(), [ManagerEventListener::getInstance(), 'onManagerStop'], 999);
// master 事件 // master 事件
ob_event_provider()->addEventListener(DriverInitEvent::getName(), [MasterEventListener::getInstance(), 'onMasterStart'], 999); ob_event_provider()->addEventListener(DriverInitEvent::getName(), [MasterEventListener::getInstance(), 'onMasterStart'], 999);
// websocket 事件
ob_event_provider()->addEventListener(WebSocketOpenEvent::getName(), [WSEventListener::getInstance(), 'onWebSocketOpen'], 999);
// 框架多进程依赖 // 框架多进程依赖
if (defined('ZM_PID_DIR') && !is_dir(ZM_PID_DIR)) { if (defined('ZM_PID_DIR') && !is_dir(ZM_STATE_DIR)) {
mkdir(ZM_PID_DIR); mkdir(ZM_STATE_DIR);
} }
} }
@@ -334,10 +330,8 @@ class Framework
$properties['version'] = self::VERSION . (LOAD_MODE === 0 ? (' (build ' . ZM_VERSION_ID . ')') : ''); $properties['version'] = self::VERSION . (LOAD_MODE === 0 ? (' (build ' . ZM_VERSION_ID . ')') : '');
// 打印 PHP 版本 // 打印 PHP 版本
$properties['php_version'] = PHP_VERSION; $properties['php_version'] = PHP_VERSION;
// 非 Windows 操作系统打印 master 进程的 pid // 打印 master 进程的 pid
if (PHP_OS_FAMILY !== 'Windows') { $properties['master_pid'] = getmypid();
$properties['master_pid'] = posix_getpid();
}
// 打印进程模型 // 打印进程模型
if ($this->driver->getName() === 'swoole') { if ($this->driver->getName() === 'swoole') {
$properties['process_mode'] = 'MST1'; $properties['process_mode'] = 'MST1';

View File

@@ -20,13 +20,13 @@ class ProcessStateManager
{ {
switch ($type) { switch ($type) {
case ZM_PROCESS_MASTER: case ZM_PROCESS_MASTER:
$file = ZM_PID_DIR . '/master.json'; $file = zm_dir(ZM_STATE_DIR . '/master.json');
if (file_exists($file)) { if (file_exists($file)) {
unlink($file); unlink($file);
} }
return; return;
case ZM_PROCESS_MANAGER: case ZM_PROCESS_MANAGER:
$file = ZM_PID_DIR . '/manager.pid'; $file = zm_dir(ZM_STATE_DIR . '/manager.pid');
if (file_exists($file)) { if (file_exists($file)) {
unlink($file); unlink($file);
} }
@@ -35,7 +35,7 @@ class ProcessStateManager
if (!is_int($id_or_name)) { if (!is_int($id_or_name)) {
throw new ZMKnownException('E99999', 'worker_id必须为整数'); throw new ZMKnownException('E99999', 'worker_id必须为整数');
} }
$file = ZM_PID_DIR . '/worker.' . $id_or_name . '.pid'; $file = zm_dir(ZM_STATE_DIR . '/worker.' . $id_or_name . '.pid');
if (file_exists($file)) { if (file_exists($file)) {
unlink($file); unlink($file);
} }
@@ -44,7 +44,7 @@ class ProcessStateManager
if (!is_string($id_or_name)) { if (!is_string($id_or_name)) {
throw new ZMKnownException('E99999', 'process_name必须为字符串'); throw new ZMKnownException('E99999', 'process_name必须为字符串');
} }
$file = ZM_PID_DIR . '/user.' . $id_or_name . '.pid'; $file = zm_dir(ZM_STATE_DIR . '/user.' . $id_or_name . '.pid');
if (file_exists($file)) { if (file_exists($file)) {
unlink($file); unlink($file);
} }
@@ -53,7 +53,7 @@ class ProcessStateManager
if (!is_int($id_or_name)) { if (!is_int($id_or_name)) {
throw new ZMKnownException('E99999', 'worker_id必须为整数'); throw new ZMKnownException('E99999', 'worker_id必须为整数');
} }
$file = ZM_PID_DIR . '/taskworker.' . $id_or_name . '.pid'; $file = zm_dir(ZM_STATE_DIR . '/taskworker.' . $id_or_name . '.pid');
if (file_exists($file)) { if (file_exists($file)) {
unlink($file); unlink($file);
} }
@@ -71,46 +71,46 @@ class ProcessStateManager
*/ */
public static function getProcessState(int $type, $id_or_name = null) public static function getProcessState(int $type, $id_or_name = null)
{ {
$file = ZM_PID_DIR; $file = ZM_STATE_DIR;
switch ($type) { switch ($type) {
case ZM_PROCESS_MASTER: case ZM_PROCESS_MASTER:
if (!file_exists($file . '/master.json')) { if (!file_exists(zm_dir($file . '/master.json'))) {
return false; return false;
} }
$json = json_decode(file_get_contents($file . '/master.json'), true); $json = json_decode(file_get_contents(zm_dir($file . '/master.json')), true);
if ($json !== null) { if ($json !== null) {
return $json; return $json;
} }
return false; return false;
case ZM_PROCESS_MANAGER: case ZM_PROCESS_MANAGER:
if (!file_exists($file . '/manager.pid')) { if (!file_exists(zm_dir($file . '/manager.pid'))) {
return false; return false;
} }
return intval(file_get_contents($file . '/manager.pid')); return intval(file_get_contents(zm_dir($file . '/manager.pid')));
case ZM_PROCESS_WORKER: case ZM_PROCESS_WORKER:
if (!is_int($id_or_name)) { if (!is_int($id_or_name)) {
throw new ZMKnownException('E99999', 'worker_id必须为整数'); throw new ZMKnownException('E99999', 'worker_id必须为整数');
} }
if (!file_exists($file . '/worker.' . $id_or_name . '.pid')) { if (!file_exists(zm_dir($file . '/worker.' . $id_or_name . '.pid'))) {
return false; return false;
} }
return intval(file_get_contents($file . '/worker.' . $id_or_name . '.pid')); return intval(file_get_contents(zm_dir($file . '/worker.' . $id_or_name . '.pid')));
case ZM_PROCESS_USER: case ZM_PROCESS_USER:
if (!is_string($id_or_name)) { if (!is_string($id_or_name)) {
throw new ZMKnownException('E99999', 'process_name必须为字符串'); throw new ZMKnownException('E99999', 'process_name必须为字符串');
} }
if (!file_exists($file . '/user.' . $id_or_name . '.pid')) { if (!file_exists(zm_dir($file . '/user.' . $id_or_name . '.pid'))) {
return false; return false;
} }
return intval(file_get_contents($file . '/user.' . $id_or_name . '.pid')); return intval(file_get_contents(zm_dir($file . '/user.' . $id_or_name . '.pid')));
case ZM_PROCESS_TASKWORKER: case ZM_PROCESS_TASKWORKER:
if (!is_int($id_or_name)) { if (!is_int($id_or_name)) {
throw new ZMKnownException('E99999', 'worker_id必须为整数'); throw new ZMKnownException('E99999', 'worker_id必须为整数');
} }
if (!file_exists($file . '/taskworker.' . $id_or_name . '.pid')) { if (!file_exists(zm_dir($file . '/taskworker.' . $id_or_name . '.pid'))) {
return false; return false;
} }
return intval(file_get_contents($file . '/taskworker.' . $id_or_name . '.pid')); return intval(file_get_contents(zm_dir($file . '/taskworker.' . $id_or_name . '.pid')));
default: default:
return false; return false;
} }
@@ -126,7 +126,7 @@ class ProcessStateManager
{ {
switch ($type) { switch ($type) {
case ZM_PROCESS_MASTER: case ZM_PROCESS_MASTER:
$file = ZM_PID_DIR . '/master.json'; $file = zm_dir(ZM_STATE_DIR . '/master.json');
$json = [ $json = [
'pid' => intval($pid), 'pid' => intval($pid),
'stdout' => $data['stdout'], 'stdout' => $data['stdout'],
@@ -135,19 +135,19 @@ class ProcessStateManager
file_put_contents($file, json_encode($json, JSON_UNESCAPED_UNICODE)); file_put_contents($file, json_encode($json, JSON_UNESCAPED_UNICODE));
return; return;
case ZM_PROCESS_MANAGER: case ZM_PROCESS_MANAGER:
$file = ZM_PID_DIR . '/manager.pid'; $file = zm_dir(ZM_STATE_DIR . '/manager.pid');
file_put_contents($file, strval($pid)); file_put_contents($file, strval($pid));
return; return;
case ZM_PROCESS_WORKER: case ZM_PROCESS_WORKER:
$file = ZM_PID_DIR . '/worker.' . $data['worker_id'] . '.pid'; $file = zm_dir(ZM_STATE_DIR . '/worker.' . $data['worker_id'] . '.pid');
file_put_contents($file, strval($pid)); file_put_contents($file, strval($pid));
return; return;
case ZM_PROCESS_USER: case ZM_PROCESS_USER:
$file = ZM_PID_DIR . '/user.' . $data['process_name'] . '.pid'; $file = zm_dir(ZM_STATE_DIR . '/user.' . $data['process_name'] . '.pid');
file_put_contents($file, strval($pid)); file_put_contents($file, strval($pid));
return; return;
case ZM_PROCESS_TASKWORKER: case ZM_PROCESS_TASKWORKER:
$file = ZM_PID_DIR . '/taskworker.' . $data['worker_id'] . '.pid'; $file = zm_dir(ZM_STATE_DIR . '/taskworker.' . $data['worker_id'] . '.pid');
file_put_contents($file, strval($pid)); file_put_contents($file, strval($pid));
return; return;
} }
@@ -155,7 +155,7 @@ class ProcessStateManager
public static function isStateEmpty(): bool public static function isStateEmpty(): bool
{ {
$ls = FileSystem::scanDirFiles(ZM_PID_DIR, false, true); $ls = FileSystem::scanDirFiles(ZM_STATE_DIR, false, true);
return empty($ls); return empty($ls);
} }
} }

View File

@@ -20,7 +20,7 @@ class FileLock
public static function lock(string $name) public static function lock(string $name)
{ {
self::$name_hash[$name] = self::$name_hash[$name] ?? md5($name); self::$name_hash[$name] = self::$name_hash[$name] ?? md5($name);
$lock_file = is_dir('/tmp') ? '/tmp' : WORKING_DIR . '.zm_' . zm_instance_id() . self::$name_hash[$name] . '.lock'; $lock_file = zm_dir(TMP_DIR . '/.zm_' . zm_instance_id() . self::$name_hash[$name] . '.lock');
self::$lock_file_handle[$name] = fopen($lock_file, 'w'); self::$lock_file_handle[$name] = fopen($lock_file, 'w');
if (self::$lock_file_handle[$name] === false) { if (self::$lock_file_handle[$name] === false) {
logger()->critical("Can not create lock file {$lock_file}\n"); logger()->critical("Can not create lock file {$lock_file}\n");

View File

@@ -102,7 +102,7 @@ class MessageUtilTest extends TestCase
public function testGetImageCQFromLocal(): void public function testGetImageCQFromLocal(): void
{ {
file_put_contents('/tmp/test.jpg', 'test'); file_put_contents(TMP_DIR . '/test.jpg', 'test');
$this->assertEquals('[CQ:image,file=base64://' . base64_encode('test') . ']', MessageUtil::getImageCQFromLocal('/tmp/test.jpg')); $this->assertEquals('[CQ:image,file=base64://' . base64_encode('test') . ']', MessageUtil::getImageCQFromLocal('/tmp/test.jpg'));
unlink('/tmp/test.jpg'); unlink('/tmp/test.jpg');
} }