optimize container services register (#129)

* optimize container services register

* fix ConnectionObject not exists

* fix phpdoc
This commit is contained in:
sunxyw 2022-05-28 17:33:01 +08:00 committed by GitHub
parent febeeadc7b
commit 458c42ae7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 75 deletions

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace ZM\Container;
use Closure;
use Psr\Log\LoggerInterface;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\Frame;
use ZM\Adapters\AdapterInterface;
use ZM\Adapters\OneBot11Adapter;
use ZM\Config\ZMConfig;
use ZM\ConnectionManager\ConnectionObject;
use ZM\Context\Context;
use ZM\Context\ContextInterface;
use ZM\Framework;
use ZM\Utils\DataProvider;
class ContainerServicesProvider
{
/**
* 注册服务
*
* ```
* 作用域:
* global: worker start
* request: request
* message: message
* connection: open, close, message
* ```
*
* @param string $scope 作用域
*/
public function registerServices(string $scope): void
{
switch ($scope) {
case 'global':
$this->registerGlobalServices(WorkerContainer::getInstance());
break;
case 'request':
$this->registerRequestServices(Container::getInstance());
break;
case 'message':
$this->registerConnectionServices(Container::getInstance());
$this->registerMessageServices(Container::getInstance());
break;
case 'connection':
$this->registerConnectionServices(Container::getInstance());
break;
default:
break;
}
}
/**
* 清理服务
*/
public function cleanup(): void
{
container()->flush();
}
/**
* 注册全局服务
*/
private function registerGlobalServices(ContainerInterface $container): void
{
$container->instance('path.working', DataProvider::getWorkingDir());
$container->instance('path.source', DataProvider::getSourceRootDir());
$container->alias('path.source', 'path.base');
$container->instance('path.config', DataProvider::getSourceRootDir() . '/config');
$container->instance('path.module_config', ZMConfig::get('global', 'config_dir'));
$container->instance('path.data', DataProvider::getDataFolder());
$container->instance('path.framework', DataProvider::getFrameworkRootDir());
$container->instance('server', Framework::$server);
$container->instance('worker_id', Framework::$server->worker_id);
$container->singleton(AdapterInterface::class, OneBot11Adapter::class);
$container->singleton(LoggerInterface::class, ZMConfig::get('logging.logger'));
}
/**
* 注册请求服务HTTP请求
*/
private function registerRequestServices(ContainerInterface $container): void
{
$context = Context::$context[zm_cid()];
$container->instance(Request::class, $context['request']);
$container->instance(Response::class, $context['response']);
$container->bind(ContextInterface::class, Closure::fromCallable('ctx'));
$container->alias(ContextInterface::class, Context::class);
}
/**
* 注册消息服务WS消息
*/
private function registerMessageServices(ContainerInterface $container): void
{
$context = Context::$context[zm_cid()];
$container->instance(Frame::class, $context['frame']); // WS 消息帧
$container->bind(ContextInterface::class, Closure::fromCallable('ctx'));
$container->alias(ContextInterface::class, Context::class);
}
/**
* 注册链接服务
*/
private function registerConnectionServices(ContainerInterface $container): void
{
$context = Context::$context[zm_cid()];
$container->instance(ConnectionObject::class, $context['connection']);
}
}

View File

@ -13,6 +13,7 @@ use ZM\Annotation\Swoole\SwooleHandler;
use ZM\Config\ZMConfig;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use ZM\Container\ContainerServicesProvider;
use ZM\Context\Context;
use ZM\Event\EventDispatcher;
use ZM\Event\SwooleEvent;
@ -34,6 +35,8 @@ class OnClose implements SwooleEvent
}
set_coroutine_params(['server' => $server, 'connection' => $conn, 'fd' => $fd]);
resolve(ContainerServicesProvider::class)->registerServices('connection');
$dispatcher1 = new EventDispatcher(OnCloseEvent::class);
$dispatcher1->setRuleFunction(function ($v) {
return $v->connect_type == ctx()->getConnection()->getName() && eval('return ' . $v->getRule() . ';');
@ -68,7 +71,9 @@ class OnClose implements SwooleEvent
$error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')';
Console::error(zm_internal_errcode('E00016') . 'Uncaught ' . get_class($e) . ' when calling "close": ' . $error_msg);
Console::trace();
} finally {
resolve(ContainerServicesProvider::class)->cleanup();
ManagerGM::popConnect($fd);
}
ManagerGM::popConnect($fd);
}
}

View File

@ -10,13 +10,11 @@ use Throwable;
use ZM\Annotation\Swoole\OnMessageEvent;
use ZM\Annotation\Swoole\OnSwooleEvent;
use ZM\Annotation\Swoole\SwooleHandler;
use ZM\ConnectionManager\ConnectionObject;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use ZM\Console\TermColor;
use ZM\Container\Container;
use ZM\Container\ContainerServicesProvider;
use ZM\Context\Context;
use ZM\Context\ContextInterface;
use ZM\Event\EventDispatcher;
use ZM\Event\SwooleEvent;
@ -33,7 +31,7 @@ class OnMessage implements SwooleEvent
$conn = ManagerGM::get($frame->fd);
set_coroutine_params(['server' => $server, 'frame' => $frame, 'connection' => $conn]);
$this->registerRequestContainerBindings($frame, $conn);
resolve(ContainerServicesProvider::class)->registerServices('message');
$dispatcher1 = new EventDispatcher(OnMessageEvent::class);
$dispatcher1->setRuleFunction(function ($v) use ($conn) {
@ -63,22 +61,7 @@ class OnMessage implements SwooleEvent
Console::error(zm_internal_errcode('E00017') . 'Uncaught ' . get_class($e) . ' when calling "message": ' . $error_msg);
Console::trace();
} finally {
container()->flush();
resolve(ContainerServicesProvider::class)->cleanup();
}
}
/**
* 注册请求容器绑定
*/
private function registerRequestContainerBindings(Frame $frame, ?ConnectionObject $conn): void
{
$container = Container::getInstance();
$container->setLogPrefix("[Container#{$frame->fd}]");
$container->instance(Frame::class, $frame);
$container->instance(ConnectionObject::class, $conn);
$container->bind(ContextInterface::class, function () {
return ctx();
});
$container->alias(ContextInterface::class, Context::class);
}
}

View File

@ -13,9 +13,9 @@ use ZM\Annotation\Swoole\OnOpenEvent;
use ZM\Annotation\Swoole\OnSwooleEvent;
use ZM\Annotation\Swoole\SwooleHandler;
use ZM\Config\ZMConfig;
use ZM\ConnectionManager\ConnectionObject;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use ZM\Container\ContainerServicesProvider;
use ZM\Context\Context;
use ZM\Event\EventDispatcher;
use ZM\Event\SwooleEvent;
@ -52,9 +52,9 @@ class OnOpen implements SwooleEvent
ManagerGM::pushConnect($request->fd, $type_conn);
$conn = ManagerGM::get($request->fd);
set_coroutine_params(['server' => $server, 'request' => $request, 'connection' => $conn, 'fd' => $request->fd]);
$conn->setOption('connect_id', strval($request->header['x-self-id'] ?? ''));
$conn->setOption('connect_id', (string) ($request->header['x-self-id'] ?? ''));
container()->instance(ConnectionObject::class, $conn);
resolve(ContainerServicesProvider::class)->registerServices('connection');
$dispatcher1 = new EventDispatcher(OnOpenEvent::class);
$dispatcher1->setRuleFunction(function ($v) {
@ -91,6 +91,8 @@ class OnOpen implements SwooleEvent
$error_msg = $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')';
Console::error(zm_internal_errcode('E00020') . 'Uncaught ' . get_class($e) . ' when calling "open": ' . $error_msg);
Console::trace();
} finally {
resolve(ContainerServicesProvider::class)->cleanup();
}
}
}

View File

@ -14,9 +14,8 @@ use ZM\Annotation\Swoole\OnSwooleEvent;
use ZM\Annotation\Swoole\SwooleHandler;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\Container\Container;
use ZM\Container\ContainerServicesProvider;
use ZM\Context\Context;
use ZM\Context\ContextInterface;
use ZM\Event\EventDispatcher;
use ZM\Event\SwooleEvent;
use ZM\Exception\InterruptException;
@ -39,7 +38,7 @@ class OnRequest implements SwooleEvent
Console::debug('Calling Swoole "request" event from fd=' . $request->fd);
set_coroutine_params(['request' => $request, 'response' => $response]);
$this->registerRequestContainerBindings($request, $response);
resolve(ContainerServicesProvider::class)->registerServices('request');
$dis1 = new EventDispatcher(OnRequestEvent::class);
$dis1->setRuleFunction(function ($v) {
@ -114,26 +113,13 @@ class OnRequest implements SwooleEvent
Console::error(zm_internal_errcode('E00023') . 'Internal server error (500), caused by ' . get_class($e) . ': ' . $e->getMessage());
Console::log($e->getTraceAsString(), 'gray');
} finally {
container()->flush();
resolve(ContainerServicesProvider::class)->cleanup();
}
}
/**
* 注册请求容器绑定
*/
private function registerRequestContainerBindings(Request $request, Response $response): void
{
$container = Container::getInstance();
// $container->setLogPrefix("[Container#{$frame->fd}]");
$container->instance(Request::class, $request);
$container->bind(ContextInterface::class, function () {
return ctx();
});
$container->alias(ContextInterface::class, Context::class);
}
/**
* 返回响应
*
* @param mixed $result
*/
private function response(Response $response, $result): void

View File

@ -9,21 +9,19 @@ namespace ZM\Event\SwooleEvent;
use Error;
use Exception;
use PDO;
use Psr\Log\LoggerInterface;
use ReflectionException;
use Swoole\Coroutine;
use Swoole\Database\PDOConfig;
use Swoole\Process;
use Swoole\WebSocket\Server;
use ZM\Adapters\AdapterInterface;
use ZM\Adapters\OneBot11Adapter;
use ZM\Annotation\AnnotationParser;
use ZM\Annotation\Swoole\OnMessageEvent;
use ZM\Annotation\Swoole\OnStart;
use ZM\Annotation\Swoole\SwooleHandler;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\Container\WorkerContainer;
use ZM\Container\ContainerServicesProvider;
use ZM\Context\Context;
use ZM\Context\ContextInterface;
use ZM\DB\DB;
@ -58,7 +56,9 @@ class OnWorkerStart implements SwooleEvent
}
unset(Context::$context[Coroutine::getCid()]);
$this->registerWorkerContainerBindings($server);
Framework::$server = $server;
resolve(ContainerServicesProvider::class)->registerServices('global');
if ($server->taskworker === false) {
ProcessManager::saveProcessState(ZM_PROCESS_WORKER, $server->worker_pid, ['worker_id' => $worker_id]);
@ -80,7 +80,6 @@ class OnWorkerStart implements SwooleEvent
});
Console::verbose("Worker #{$server->worker_id} starting");
Framework::$server = $server;
// ZMBuf::resetCache(); //清空变量缓存
// ZMBuf::set("wait_start", []); //添加队列在workerStart运行完成前先让其他协程等待执行
@ -134,7 +133,6 @@ class OnWorkerStart implements SwooleEvent
// 这里是TaskWorker初始化的内容部分
ProcessManager::saveProcessState(ZM_PROCESS_TASKWORKER, $server->worker_pid, ['worker_id' => $worker_id]);
try {
Framework::$server = $server;
$this->loadAnnotations();
Console::verbose('TaskWorker #' . $server->worker_id . ' started');
} catch (Exception $e) {
@ -297,30 +295,6 @@ class OnWorkerStart implements SwooleEvent
}
}
/**
* 注册进程容器绑定
*/
private function registerWorkerContainerBindings(Server $server): void
{
$container = WorkerContainer::getInstance();
$container->setLogPrefix("[WorkerContainer#{$server->worker_id}]");
// 路径
$container->instance('path.working', DataProvider::getWorkingDir());
$container->instance('path.source', DataProvider::getSourceRootDir());
$container->alias('path.source', 'path.base');
$container->instance('path.config', DataProvider::getSourceRootDir() . '/config');
$container->instance('path.module_config', ZMConfig::get('global', 'config_dir'));
$container->instance('path.data', DataProvider::getDataFolder());
$container->instance('path.framework', DataProvider::getFrameworkRootDir());
// 基础
$container->instance('server', $server);
$container->instance('worker_id', $server->worker_id);
$container->singleton(AdapterInterface::class, OneBot11Adapter::class);
$container->singleton(LoggerInterface::class, ZMConfig::get('logging.logger'));
}
private function gatherWorkerStartStatus()
{
SpinLock::lock('worker_start_status');

View File

@ -8,7 +8,6 @@ use Swoole\Server;
use ZM\Annotation\Swoole\SwooleHandler;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use ZM\Container\WorkerContainer;
use ZM\Event\SwooleEvent;
use ZM\Store\LightCache;
use ZM\Utils\Manager\ProcessManager;
@ -21,8 +20,6 @@ class OnWorkerStop implements SwooleEvent
{
public function onCall(Server $server, $worker_id)
{
WorkerContainer::getInstance()->flush();
if ($worker_id == (ZMConfig::get('global.worker_cache.worker') ?? 0)) {
LightCache::savePersistence();
}