2021-03-18 14:56:35 +08:00
|
|
|
<?php /** @noinspection PhpUnused */
|
2021-01-20 16:11:04 +08:00
|
|
|
|
|
|
|
|
|
2021-06-16 00:17:30 +08:00
|
|
|
namespace ZM\Utils\Manager;
|
2021-01-20 16:11:04 +08:00
|
|
|
|
|
|
|
|
|
2021-06-16 00:17:30 +08:00
|
|
|
use Swoole\Coroutine;
|
2021-03-25 16:18:09 +08:00
|
|
|
use ZM\Annotation\CQ\CQCommand;
|
2021-03-24 23:34:46 +08:00
|
|
|
use ZM\Annotation\Swoole\OnPipeMessageEvent;
|
|
|
|
|
use ZM\Console\Console;
|
|
|
|
|
use ZM\Event\EventDispatcher;
|
2021-03-25 16:18:09 +08:00
|
|
|
use ZM\Event\EventManager;
|
2021-03-24 23:34:46 +08:00
|
|
|
use ZM\Store\LightCache;
|
|
|
|
|
use ZM\Store\LightCacheInside;
|
|
|
|
|
use ZM\Store\WorkerCache;
|
|
|
|
|
|
2021-01-20 16:11:04 +08:00
|
|
|
class ProcessManager
|
|
|
|
|
{
|
2021-03-24 23:34:46 +08:00
|
|
|
public static function workerAction($src_worker_id, $data) {
|
|
|
|
|
$server = server();
|
|
|
|
|
switch ($data["action"] ?? '') {
|
2021-03-25 16:18:09 +08:00
|
|
|
case 'add_short_command':
|
2021-03-29 15:34:24 +08:00
|
|
|
Console::verbose("Adding short command " . $data["data"][0]);
|
2021-03-25 16:18:09 +08:00
|
|
|
$obj = new CQCommand();
|
|
|
|
|
$obj->method = quick_reply_closure($data["data"][1]);
|
|
|
|
|
$obj->match = $data["data"][0];
|
|
|
|
|
$obj->class = "";
|
|
|
|
|
EventManager::addEvent(CQCommand::class, $obj);
|
|
|
|
|
break;
|
2021-03-24 23:34:46 +08:00
|
|
|
case "eval":
|
|
|
|
|
eval($data["data"]);
|
|
|
|
|
break;
|
|
|
|
|
case "call_static":
|
|
|
|
|
call_user_func_array([$data["data"]["class"], $data["data"]["method"]], $data["data"]["params"]);
|
|
|
|
|
break;
|
|
|
|
|
case "save_persistence":
|
|
|
|
|
LightCache::savePersistence();
|
|
|
|
|
break;
|
|
|
|
|
case "resume_ws_message":
|
|
|
|
|
$obj = $data["data"];
|
2021-06-16 00:17:30 +08:00
|
|
|
Coroutine::resume($obj["coroutine"]);
|
2021-03-24 23:34:46 +08:00
|
|
|
break;
|
|
|
|
|
case "getWorkerCache":
|
|
|
|
|
$r = WorkerCache::get($data["key"]);
|
|
|
|
|
$action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r];
|
|
|
|
|
$server->sendMessage(json_encode($action, 256), $src_worker_id);
|
|
|
|
|
break;
|
|
|
|
|
case "setWorkerCache":
|
|
|
|
|
$r = WorkerCache::set($data["key"], $data["value"]);
|
|
|
|
|
$action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r];
|
|
|
|
|
$server->sendMessage(json_encode($action, 256), $src_worker_id);
|
|
|
|
|
break;
|
|
|
|
|
case "unsetWorkerCache":
|
|
|
|
|
$r = WorkerCache::unset($data["key"]);
|
|
|
|
|
$action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r];
|
|
|
|
|
$server->sendMessage(json_encode($action, 256), $src_worker_id);
|
|
|
|
|
break;
|
|
|
|
|
case "hasKeyWorkerCache":
|
|
|
|
|
$r = WorkerCache::hasKey($data["key"], $data["subkey"]);
|
|
|
|
|
$action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r];
|
|
|
|
|
$server->sendMessage(json_encode($action, 256), $src_worker_id);
|
|
|
|
|
break;
|
|
|
|
|
case "asyncAddWorkerCache":
|
|
|
|
|
WorkerCache::add($data["key"], $data["value"], true);
|
|
|
|
|
break;
|
|
|
|
|
case "asyncSubWorkerCache":
|
|
|
|
|
WorkerCache::sub($data["key"], $data["value"], true);
|
|
|
|
|
break;
|
|
|
|
|
case "asyncSetWorkerCache":
|
|
|
|
|
WorkerCache::set($data["key"], $data["value"], true);
|
|
|
|
|
break;
|
|
|
|
|
case "asyncUnsetWorkerCache":
|
|
|
|
|
WorkerCache::unset($data["key"], true);
|
|
|
|
|
break;
|
|
|
|
|
case "addWorkerCache":
|
|
|
|
|
$r = WorkerCache::add($data["key"], $data["value"]);
|
|
|
|
|
$action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r];
|
|
|
|
|
$server->sendMessage(json_encode($action, 256), $src_worker_id);
|
|
|
|
|
break;
|
|
|
|
|
case "subWorkerCache":
|
|
|
|
|
$r = WorkerCache::sub($data["key"], $data["value"]);
|
|
|
|
|
$action = ["action" => "returnWorkerCache", "cid" => $data["cid"], "value" => $r];
|
|
|
|
|
$server->sendMessage(json_encode($action, 256), $src_worker_id);
|
|
|
|
|
break;
|
|
|
|
|
case "returnWorkerCache":
|
|
|
|
|
WorkerCache::$transfer[$data["cid"]] = $data["value"];
|
|
|
|
|
zm_resume($data["cid"]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
$dispatcher = new EventDispatcher(OnPipeMessageEvent::class);
|
|
|
|
|
$dispatcher->setRuleFunction(function (OnPipeMessageEvent $v) use ($data) {
|
|
|
|
|
return $v->action == $data["action"];
|
|
|
|
|
});
|
|
|
|
|
$dispatcher->dispatchEvents($data);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function sendActionToWorker($worker_id, $action, $data) {
|
|
|
|
|
$obj = ["action" => $action, "data" => $data];
|
|
|
|
|
if (server()->worker_id === -1 && server()->getManagerPid() != posix_getpid()) {
|
2021-06-16 00:17:30 +08:00
|
|
|
Console::warning(zm_internal_errcode("E00022") . "Cannot send worker action from master or manager process!");
|
2021-03-24 23:34:46 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (server()->worker_id == $worker_id) {
|
|
|
|
|
self::workerAction($worker_id, $obj);
|
|
|
|
|
} else {
|
|
|
|
|
server()->sendMessage(json_encode($obj), $worker_id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function resumeAllWorkerCoroutines() {
|
|
|
|
|
if (server()->worker_id === -1) {
|
2021-03-29 15:34:24 +08:00
|
|
|
Console::warning("Cannot call '" . __FUNCTION__ . "' in non-worker process!");
|
2021-03-24 23:34:46 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2021-06-16 00:17:30 +08:00
|
|
|
foreach ((LightCacheInside::get("wait_api", "wait_api") ?? []) as $v) {
|
2021-03-29 15:34:24 +08:00
|
|
|
if (isset($v["coroutine"], $v["worker_id"])) {
|
2021-06-16 00:17:30 +08:00
|
|
|
if (server()->worker_id == $v["worker_id"]) Coroutine::resume($v["coroutine"]);
|
2021-03-24 23:34:46 +08:00
|
|
|
}
|
|
|
|
|
}
|
2021-01-20 16:11:04 +08:00
|
|
|
}
|
|
|
|
|
}
|