update to 2.4.3 version (build 403)

add config: swoole.max_wait_time (default 5)
add constant MAIN_WORKER
add getExpireTS() for LightCache
fix savePersistence() bug
add zm_go() to prevent errors
This commit is contained in:
jerry
2021-03-29 15:34:24 +08:00
parent 202c8aee77
commit 6b872c6f74
32 changed files with 1280 additions and 882 deletions

View File

@@ -68,7 +68,7 @@ class CoMessage
LightCacheInside::set("wait_api", "wait_api", $all);
SpinLock::unlock("wait_api");
if ($all[$last]["worker_id"] != server()->worker_id) {
ZMUtil::sendActionToWorker($all[$last]["worker_id"], "resume_ws_message", $all[$last]);
ProcessManager::sendActionToWorker($all[$last]["worker_id"], "resume_ws_message", $all[$last]);
} else {
Co::resume($all[$last]["coroutine"]);
}

View File

@@ -20,7 +20,7 @@ class ProcessManager
$server = server();
switch ($data["action"] ?? '') {
case 'add_short_command':
Console::verbose("Adding short command ".$data["data"][0]);
Console::verbose("Adding short command " . $data["data"][0]);
$obj = new CQCommand();
$obj->method = quick_reply_closure($data["data"][1]);
$obj->match = $data["data"][0];
@@ -111,11 +111,11 @@ class ProcessManager
public static function resumeAllWorkerCoroutines() {
if (server()->worker_id === -1) {
Console::warning("Cannot call '".__FUNCTION__."' in non-worker process!");
Console::warning("Cannot call '" . __FUNCTION__ . "' in non-worker process!");
return;
}
foreach ((LightCacheInside::get("wait_api", "wait_api") ?? []) as $k => $v) {
if (($v["result"] ?? false) === null && isset($v["coroutine"], $v["worker_id"])) {
if (isset($v["coroutine"], $v["worker_id"])) {
if (server()->worker_id == $v["worker_id"]) Co::resume($v["coroutine"]);
}
}

View File

@@ -4,17 +4,20 @@
namespace ZM\Utils;
use Doctrine\Common\Annotations\AnnotationReader;
use Exception;
use Psy\Shell;
use ReflectionClass;
use Swoole\Process;
use ZM\Annotation\Command\TerminalCommand;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use ZM\Event\EventDispatcher;
use ZM\Event\EventManager;
use ZM\Framework;
class Terminal
{
public static $default_commands = false;
/**
* @param string $cmd
* @return bool
@@ -23,84 +26,22 @@ class Terminal
* @throws Exception
*/
public static function executeCommand(string $cmd) {
if (self::$default_commands === false) {
self::init();
}
$it = explodeMsg($cmd);
switch ($it[0] ?? '') {
case 'help':
$help[] = "exit | q:\t断开远程终端";
$help[] = "logtest:\t输出所有可以打印的log等级示例消息用于测试Console";
$help[] = "call:\t\t用于执行不需要参数的动态函数,比如 `call \Module\Example\Hello hitokoto`";
$help[] = "level:\t\t设置log等级例如 `level 0|1|2|3|4`";
$help[] = "bc:\t\teval执行代码但输入必须是将代码base64之后的如 `bc em1faW5mbygn5L2g5aW9Jyk7`";
$help[] = "stop:\t\t停止服务器";
$help[] = "reload | r:\t热重启用户编写的模块代码";
foreach((EventManager::$events[TerminalCommand::class] ?? []) as $v) {
$help[]=$v->command.":\t\t".(empty($v->description) ? "<用户自定义指令>" : $v->description);
}
echo implode("\n", $help) . PHP_EOL;
return true;
case 'logtest':
Console::log(date("[H:i:s]") . " [L] This is normal msg. (0)");
Console::error("This is error msg. (0)");
Console::warning("This is warning msg. (1)");
Console::info("This is info msg. (2)");
Console::success("This is success msg. (2)");
Console::verbose("This is verbose msg. (3)");
Console::debug("This is debug msg. (4)");
return true;
case 'call':
$class_name = $it[1];
$function_name = $it[2];
$class = new $class_name([]);
$r = $class->$function_name();
if (is_string($r)) Console::success($r);
return true;
case 'psysh':
if (Framework::$argv["disable-coroutine"]) {
(new Shell())->run();
} else
Console::error("Only \"--disable-coroutine\" mode can use psysh!!!");
return true;
case 'level':
$level = intval(is_numeric($it[1] ?? 99) ? ($it[1] ?? 99) : 99);
if ($level > 4 || $level < 0) Console::warning("Usage: 'level 0|1|2|3|4'");
else Console::setLevel($level) || Console::success("Success!!");
break;
case 'bc':
$code = base64_decode($it[1] ?? '', true);
try {
eval($code);
} catch (Exception $e) {
}
return true;
case 'echo':
Console::info($it[1]);
return true;
case 'color':
Console::log($it[2], $it[1]);
return true;
case 'stop':
ZMUtil::stop();
return false;
case 'reload':
case 'r':
ZMUtil::reload();
return false;
case '':
return true;
default:
$dispatcher = new EventDispatcher(TerminalCommand::class);
$dispatcher->setRuleFunction(function ($v) use ($it) {
/** @var TerminalCommand $v */
return $v->command == $it[0];
});
$dispatcher->setReturnFunction(function () {
EventDispatcher::interrupt('none');
});
$dispatcher->dispatchEvents($it);
if ($dispatcher->store !== 'none') {
Console::info("Command not found: " . $cmd);
return true;
}
$dispatcher = new EventDispatcher(TerminalCommand::class);
$dispatcher->setRuleFunction(function ($v) use ($it) {
/** @var TerminalCommand $v */
return $v->command == $it[0] || $v->alias == $it[0];
});
$dispatcher->setReturnFunction(function () {
EventDispatcher::interrupt('none');
});
$dispatcher->dispatchEvents($it);
if ($dispatcher->store !== 'none') {
Console::info("Command not found: " . $cmd);
return true;
}
return false;
}
@@ -119,4 +60,129 @@ class Terminal
server()->send($v->getFd(), ">>> ");
}
}
public static function init() {
Console::debug("Initializing Terminal...");
foreach ((EventManager::$events[TerminalCommand::class] ?? []) as $v) {
if ($v->command == "help") {
self::$default_commands = true;
break;
}
}
$class = new Terminal();
$reader = new AnnotationReader();
$reflection = new ReflectionClass($class);
foreach ($reflection->getMethods() as $k => $v) {
$r = $reader->getMethodAnnotation($v, TerminalCommand::class);
if ($r !== null) {
Console::debug("adding command " . $r->command);
$r->class = Terminal::class;
$r->method = $v->getName();
EventManager::addEvent(TerminalCommand::class, $r);
}
}
self::$default_commands = true;
}
/**
* @TerminalCommand(command="help",alias="h",description="显示帮助菜单")
*/
public function help() {
$help = [];
foreach ((EventManager::$events[TerminalCommand::class] ?? []) as $v) {
/** @var TerminalCommand $v */
$cmd = $v->command . ($v->alias !== "" ? (" | " . $v->alias) : "");
$painted = Console::setColor($v->command, "green") . ($v->alias !== "" ? (" | " . Console::setColor($v->alias, "green")) : "");
$help[] = $painted . ":" . str_pad("", 16 - strlen($cmd) - 1) . ($v->description === "" ? "<无描述>" : $v->description);
}
echo implode("\n", $help) . PHP_EOL;
}
/**
* @TerminalCommand(command="status",description="显示Swoole Server运行状态需要安装league/climate组件")
* @noinspection PhpFullyQualifiedNameUsageInspection
*/
public function status() {
if (!class_exists("\League\CLImate\CLImate")) {
Console::warning("你还没有安装 league/climate 组件,无法使用此功能!");
return;
}
$climate = new \League\CLImate\CLImate;
$climate->output->addDefault('buffer');
$objs = server()->stats();
$climate->columns($objs);
$obj = $climate->output->get('buffer')->get();
$climate->output->get("buffer")->clean();
echo $obj;
}
/**
* @TerminalCommand(command="logtest",description="测试log的显示等级")
*/
public function testlog() {
Console::log(date("[H:i:s]") . " [L] This is normal msg. (0)");
Console::error("This is error msg. (0)");
Console::warning("This is warning msg. (1)");
Console::info("This is info msg. (2)");
Console::success("This is success msg. (2)");
Console::verbose("This is verbose msg. (3)");
Console::debug("This is debug msg. (4)");
}
/**
* @TerminalCommand(command="call",description="用于执行不需要参数的动态函数,比如 `call \Module\Example\Hello hitokoto`")
* @param $it
*/
public function call($it) {
$class_name = $it[1];
$function_name = $it[2];
$class = new $class_name([]);
$r = $class->$function_name();
if (is_string($r)) Console::success($r);
}
/**
* @TerminalCommand(command="level",description="设置log等级例如 `level 0|1|2|3|4`")
* @param $it
*/
public function level($it) {
$level = intval(is_numeric($it[1] ?? 99) ? ($it[1] ?? 99) : 99);
if ($level > 4 || $level < 0) Console::warning("Usage: 'level 0|1|2|3|4'");
else Console::setLevel($level) || Console::success("Success!!");
}
/**
* @TerminalCommand(command="bc",description="eval执行代码但输入必须是将代码base64之后的如 `bc em1faW5mbygn5L2g5aW9Jyk7`")
* @param $it
*/
public function bc($it) {
$code = base64_decode($it[1] ?? '', true);
try {
eval($code);
} catch (Exception $e) {
}
}
/**
* @TerminalCommand(command="echo",description="输出内容,用法:`echo hello`")
* @param $it
*/
public function echoI($it) {
Console::info($it[1]);
}
/**
* @TerminalCommand(command="stop",description="停止框架")
*/
public function stop() {
Process::kill(server()->master_pid, SIGTERM);
}
/**
* @TerminalCommand(command="reload",alias="r",description="重启框架(重载用户代码)")
*/
public function reload() {
Process::kill(server()->master_pid, SIGUSR1);
}
}

View File

@@ -27,15 +27,13 @@ class ZMUtil
Process::kill(zm_atomic("_#worker_" . $i)->get(), SIGUSR1);
}
server()->shutdown();
server()->stop();
}
/**
* @throws Exception
*/
public static function reload() {
zm_atomic("_int_is_reload")->set(1);
system("kill -INT " . intval(server()->master_pid));
Process::kill(server()->master_pid, SIGUSR1);
}
public static function getModInstance($class) {
@@ -47,11 +45,6 @@ class ZMUtil
}
}
public static function sendActionToWorker($target_id, $action, $data) {
Console::verbose($action . ": " . $data);
server()->sendMessage(json_encode(["action" => $action, "data" => $data]), $target_id);
}
/**
* 在工作进程中返回可以通过reload重新加载的php文件列表
* @return string[]|string[][]