mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-10 18:02:55 +00:00
perf: 优化初始化数据
This commit is contained in:
parent
6fda0bd548
commit
0c70613865
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Hhxsv5\LaravelS\Swoole\Events\ServerStartInterface;
|
||||
use Swoole\Http\Server;
|
||||
|
||||
class ServerStartEvent implements ServerStartInterface
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(Server $server)
|
||||
{
|
||||
$server->startMsecTime = $this->msecTime();
|
||||
}
|
||||
|
||||
private function msecTime()
|
||||
{
|
||||
list($msec, $sec) = explode(' ', microtime());
|
||||
$time = explode(".", $sec . ($msec * 1000));
|
||||
return $time[0];
|
||||
}
|
||||
}
|
||||
@ -17,8 +17,15 @@ class WorkerStartEvent implements WorkerStartInterface
|
||||
|
||||
public function handle(Server $server, $workerId)
|
||||
{
|
||||
if (isset($server->startMsecTime) && Cache::get("swooleServerStartMsecTime") != $server->startMsecTime) {
|
||||
Cache::forever("swooleServerStartMsecTime", $server->startMsecTime);
|
||||
// 仅在Worker进程启动时执行一次初始化代码
|
||||
$initTable = app('swoole')->initFlagTable;
|
||||
if ($initTable->incr('init_flag', 'value') === 1) {
|
||||
$this->handleFirstWorkerTasks();
|
||||
}
|
||||
}
|
||||
|
||||
private function handleFirstWorkerTasks()
|
||||
{
|
||||
WebSocket::query()->delete();
|
||||
//
|
||||
$all = Base::json2array(Cache::get("User::online:all"));
|
||||
@ -26,5 +33,4 @@ class WorkerStartEvent implements WorkerStartInterface
|
||||
Cache::forget("User::online:" . $userid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2107,8 +2107,6 @@ class UsersController extends AbstractController
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
global $_A;
|
||||
if (!isset($_A["__annual__report_".$user->userid])) {
|
||||
$year = '2023';
|
||||
$time = '2300-01-01 00:00:01';
|
||||
$prefix = \DB::getTablePrefix();
|
||||
@ -2194,7 +2192,7 @@ class UsersController extends AbstractController
|
||||
->first();
|
||||
|
||||
//
|
||||
$_A["__annual__report_".$user->userid] = [
|
||||
$data = [
|
||||
// 本人信息
|
||||
'user' => [
|
||||
'userid' => $user->userid,
|
||||
@ -2259,8 +2257,7 @@ class UsersController extends AbstractController
|
||||
->get()
|
||||
]
|
||||
];
|
||||
}
|
||||
//
|
||||
return Base::retSuccess('success', $_A["__annual__report_".$user->userid]);
|
||||
return Base::retSuccess('success', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ namespace App\Http\Middleware;
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use App\Module\Doo;
|
||||
use App\Services\RequestContext;
|
||||
use Closure;
|
||||
|
||||
class WebApi
|
||||
@ -18,11 +19,14 @@ class WebApi
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
global $_A;
|
||||
$_A = [];
|
||||
// 为每个请求生成唯一ID
|
||||
$request->requestId = RequestContext::generateRequestId();
|
||||
RequestContext::set('start_time', microtime(true));
|
||||
|
||||
// 加载Doo类
|
||||
Doo::load();
|
||||
|
||||
// 解密请求内容
|
||||
$encrypt = Doo::pgpParseStr($request->header('encrypt'));
|
||||
if ($request->isMethod('post')) {
|
||||
$version = $request->header('version');
|
||||
@ -47,6 +51,7 @@ class WebApi
|
||||
$request->setTrustedProxies([$request->getClientIp()], $request::HEADER_X_FORWARDED_PROTO);
|
||||
}
|
||||
|
||||
// 执行下一个中间件
|
||||
$response = $next($request);
|
||||
|
||||
// 加密返回内容
|
||||
@ -57,6 +62,16 @@ class WebApi
|
||||
}
|
||||
}
|
||||
|
||||
// 返回响应
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
// 请求结束后清理上下文
|
||||
RequestContext::clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ namespace App\Models;
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Module\Base;
|
||||
use App\Module\Doo;
|
||||
use App\Services\RequestContext;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use Request;
|
||||
@ -435,9 +436,8 @@ class User extends AbstractModel
|
||||
*/
|
||||
private static function authInfo()
|
||||
{
|
||||
global $_A;
|
||||
if (isset($_A["__static_auth"])) {
|
||||
return $_A["__static_auth"];
|
||||
if (RequestContext::has('auth')) {
|
||||
return RequestContext::get('auth');
|
||||
}
|
||||
if (Doo::userId() > 0
|
||||
&& !Doo::userExpired()
|
||||
@ -459,9 +459,9 @@ class User extends AbstractModel
|
||||
$user->updateInstance($upArray);
|
||||
$user->save();
|
||||
}
|
||||
return $_A["__static_auth"] = $user;
|
||||
return RequestContext::save('auth', $user);
|
||||
}
|
||||
return $_A["__static_auth"] = false;
|
||||
return RequestContext::save('auth', false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -497,20 +497,19 @@ class User extends AbstractModel
|
||||
*/
|
||||
public static function userid2basic($userid, $addField = [])
|
||||
{
|
||||
global $_A;
|
||||
if (empty($userid)) {
|
||||
return null;
|
||||
}
|
||||
$userid = intval($userid);
|
||||
if (isset($_A["__static_userid2basic_" . $userid])) {
|
||||
return $_A["__static_userid2basic_" . $userid];
|
||||
if (RequestContext::has("userid2basic_" . $userid)) {
|
||||
return RequestContext::get("userid2basic_" . $userid);
|
||||
}
|
||||
$userInfo = self::whereUserid($userid)->select(array_merge(User::$basicField, $addField))->first();
|
||||
if ($userInfo) {
|
||||
$userInfo->online = $userInfo->getOnlineStatus();
|
||||
$userInfo->department_name = $userInfo->getDepartmentName();
|
||||
}
|
||||
return $_A["__static_userid2basic_" . $userid] = ($userInfo ?: []);
|
||||
return RequestContext::save("userid2basic_" . $userid, $userInfo ?: []);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -284,7 +284,7 @@ class UserBot extends AbstractModel
|
||||
];
|
||||
}
|
||||
} elseif (preg_match('/^(manual|locat|face|checkin)-(\d+)$/i', $mac, $match)) {
|
||||
$type = strtolower(str_replace('checkin', 'face', $match[1]));
|
||||
$type = str_replace('checkin', 'face', strtolower($match[1]));
|
||||
$mac = intval($match[2]);
|
||||
$remark = match ($type) {
|
||||
'manual' => $setting['manual_remark'] ?: 'Manual',
|
||||
|
||||
@ -5,6 +5,7 @@ namespace App\Module;
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Tmp;
|
||||
use App\Services\RequestContext;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use League\CommonMark\CommonMarkConverter;
|
||||
@ -125,11 +126,10 @@ class Base
|
||||
*/
|
||||
public static function getClientVersion()
|
||||
{
|
||||
global $_A;
|
||||
if (!isset($_A["__static_client_version"])) {
|
||||
$_A["__static_client_version"] = self::headerOrInput('version') ?: '0.0.1';
|
||||
if (RequestContext::has('client_version')) {
|
||||
return RequestContext::get('client_version');
|
||||
}
|
||||
return $_A["__static_client_version"];
|
||||
return RequestContext::save('client_version', self::headerOrInput('version') ?: '0.0.1');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -757,7 +757,6 @@ class Base
|
||||
*/
|
||||
public static function fillUrl($str = '')
|
||||
{
|
||||
global $_A;
|
||||
if (is_array($str)) {
|
||||
foreach ($str as $key => $item) {
|
||||
$str[$key] = Base::fillUrl($item);
|
||||
@ -776,7 +775,7 @@ class Base
|
||||
) {
|
||||
return $str;
|
||||
} else {
|
||||
if ($_A['__fill_url_remote_url'] === true) {
|
||||
if (RequestContext::has('fill_url_remote_url')) {
|
||||
return "{{RemoteURL}}" . $str;
|
||||
}
|
||||
try {
|
||||
@ -1298,12 +1297,11 @@ class Base
|
||||
*/
|
||||
public static function setting($setname, $array = false, $isUpdate = false)
|
||||
{
|
||||
global $_A;
|
||||
if (empty($setname)) {
|
||||
return [];
|
||||
}
|
||||
if ($array === false && isset($_A["__static_setting_" . $setname])) {
|
||||
return $_A["__static_setting_" . $setname];
|
||||
if ($array === false && RequestContext::has('setting_' . $setname)) {
|
||||
return RequestContext::get('setting_' . $setname);
|
||||
}
|
||||
$setting = [];
|
||||
$row = Setting::whereName($setname)->first();
|
||||
@ -1322,8 +1320,7 @@ class Base
|
||||
$row->updateInstance(['setting' => $setting]);
|
||||
$row->save();
|
||||
}
|
||||
$_A["__static_setting_" . $setname] = $setting;
|
||||
return $setting;
|
||||
return RequestContext::save('setting_' . $setname, $setting);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1739,16 +1736,11 @@ class Base
|
||||
|
||||
/**
|
||||
* 获取时间戳
|
||||
* @param bool $refresh
|
||||
* @return int
|
||||
*/
|
||||
public static function time($refresh = false)
|
||||
public static function time()
|
||||
{
|
||||
global $_A;
|
||||
if (!isset($_A["__static_time"]) || $refresh === true) {
|
||||
$_A["__static_time"] = time();
|
||||
}
|
||||
return $_A["__static_time"];
|
||||
return intval(RequestContext::get("start_time", time()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1833,8 +1825,9 @@ class Base
|
||||
*/
|
||||
public static function getIp()
|
||||
{
|
||||
global $_A;
|
||||
if (!isset($_A["__static_ip"])) {
|
||||
if (RequestContext::has("static_ip")) {
|
||||
return RequestContext::get("static_ip");
|
||||
}
|
||||
if (getenv('HTTP_CLIENT_IP') and strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
|
||||
$onlineip = getenv('HTTP_CLIENT_IP');
|
||||
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) and $_SERVER['HTTP_CLIENT_IP'] and strcasecmp($_SERVER['HTTP_CLIENT_IP'], 'unknown')) {
|
||||
@ -1853,9 +1846,7 @@ class Base
|
||||
$onlineip = '0,0,0,0';
|
||||
}
|
||||
preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $onlineip, $match);
|
||||
$_A["__static_ip"] = $match ? ($match[0] ?: 'unknown') : '';
|
||||
}
|
||||
return $_A["__static_ip"];
|
||||
return RequestContext::save("static_ip", $match ? ($match[0] ?: 'unknown') : '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
86
app/Module/Table/AbstractData.php
Normal file
86
app/Module/Table/AbstractData.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Module\Table;
|
||||
|
||||
use ReflectionClass;
|
||||
use Swoole\Table;
|
||||
|
||||
abstract class AbstractData
|
||||
{
|
||||
/** @var self */
|
||||
protected static $instance = null;
|
||||
|
||||
/** @var Table */
|
||||
protected $table;
|
||||
|
||||
protected function getTableName(): string
|
||||
{
|
||||
$className = (new ReflectionClass(static::class))->getShortName();
|
||||
return lcfirst($className) . 'Table';
|
||||
}
|
||||
|
||||
private function __clone() {}
|
||||
private function __wakeup() {}
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
$this->table = app('swoole')->{$this->getTableName()};
|
||||
}
|
||||
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
public static function instance()
|
||||
{
|
||||
if (static::$instance === null) {
|
||||
static::$instance = new static();
|
||||
}
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
public static function set($key, $value)
|
||||
{
|
||||
return self::instance()->table->set($key, ['value' => $value]);
|
||||
}
|
||||
|
||||
public static function get($key, $default = null)
|
||||
{
|
||||
$data = self::instance()->table->get($key);
|
||||
return $data ? $data['value'] : $default;
|
||||
}
|
||||
|
||||
public static function del($key)
|
||||
{
|
||||
return self::instance()->table->del($key);
|
||||
}
|
||||
|
||||
public static function exist($key)
|
||||
{
|
||||
return self::instance()->table->exist($key);
|
||||
}
|
||||
|
||||
public static function setMultiple(array $items)
|
||||
{
|
||||
foreach ($items as $key => $value) {
|
||||
self::set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public static function clear()
|
||||
{
|
||||
foreach (self::instance()->table as $key => $row) {
|
||||
self::del($key);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAll()
|
||||
{
|
||||
$result = [];
|
||||
foreach (self::instance()->table as $key => $row) {
|
||||
$result[$key] = $row['value'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
7
app/Module/Table/GlobalData.php
Normal file
7
app/Module/Table/GlobalData.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace App\Module\Table;
|
||||
|
||||
class GlobalData extends AbstractData
|
||||
{
|
||||
}
|
||||
22
app/Module/Table/OnlineData.php
Normal file
22
app/Module/Table/OnlineData.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Module\Table;
|
||||
|
||||
class OnlineData extends AbstractData
|
||||
{
|
||||
public static function incr($userid)
|
||||
{
|
||||
$key = "online::" . $userid;
|
||||
$value = intval(self::get($key, 0));
|
||||
self::set($key, ++$value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function decr($userid)
|
||||
{
|
||||
$key = "online::" . $userid;
|
||||
$value = intval(self::get($key, 0));
|
||||
self::set($key, --$value);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
142
app/Services/RequestContext.php
Normal file
142
app/Services/RequestContext.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RequestContext
|
||||
{
|
||||
/** @var array<string, array<string, mixed>> */
|
||||
private static array $context = [];
|
||||
|
||||
private const REQUEST_ID_PREFIX = 'req_';
|
||||
|
||||
/**
|
||||
* 生成请求唯一ID
|
||||
*/
|
||||
public static function generateRequestId(): string
|
||||
{
|
||||
return self::REQUEST_ID_PREFIX . uniqid() . mt_rand(10000, 99999);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求ID
|
||||
*/
|
||||
private static function getCurrentRequestId(): ?string
|
||||
{
|
||||
/** @var Request $request */
|
||||
$request = request();
|
||||
return $request?->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求上下文
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param string|null $requestId
|
||||
* @return void
|
||||
*/
|
||||
public static function set(string $key, mixed $value, ?string $requestId = null): void
|
||||
{
|
||||
$requestId = $requestId ?? self::getCurrentRequestId();
|
||||
if ($requestId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$context[$requestId] ??= [];
|
||||
self::$context[$requestId][$key] = $value;
|
||||
}
|
||||
|
||||
// 与 set 方法的区别是,save 方法会返回传入的 value 值
|
||||
public static function save(string $key, mixed $value, ?string $requestId = null): mixed
|
||||
{
|
||||
self::set($key, $value, $requestId);
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求上下文
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @param string|null $requestId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get(string $key, mixed $default = null, ?string $requestId = null): mixed
|
||||
{
|
||||
$requestId = $requestId ?? self::getCurrentRequestId();
|
||||
if ($requestId === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return self::$context[$requestId][$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断请求上下文是否存在
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|null $requestId
|
||||
* @return bool
|
||||
*/
|
||||
public static function has(string $key, ?string $requestId = null): bool
|
||||
{
|
||||
$requestId = $requestId ?? self::getCurrentRequestId();
|
||||
if ($requestId === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset(self::$context[$requestId][$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理请求上下文
|
||||
*
|
||||
* @param string|null $requestId
|
||||
* @return void
|
||||
*/
|
||||
public static function clear(?string $requestId = null): void
|
||||
{
|
||||
$requestId = $requestId ?? self::getCurrentRequestId();
|
||||
if ($requestId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset(self::$context[$requestId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的所有上下文数据
|
||||
*
|
||||
* @param string|null $requestId
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function getAll(?string $requestId = null): array
|
||||
{
|
||||
$requestId = $requestId ?? self::getCurrentRequestId();
|
||||
if ($requestId === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return self::$context[$requestId] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置上下文数据
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string|null $requestId
|
||||
* @return void
|
||||
*/
|
||||
public static function setMultiple(array $data, ?string $requestId = null): void
|
||||
{
|
||||
$requestId = $requestId ?? self::getCurrentRequestId();
|
||||
if ($requestId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$context[$requestId] ??= [];
|
||||
self::$context[$requestId] = array_merge(self::$context[$requestId], $data);
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ use App\Models\WebSocketDialogMsg;
|
||||
use App\Models\WebSocketDialogMsgRead;
|
||||
use App\Module\Base;
|
||||
use App\Module\Doo;
|
||||
use App\Services\RequestContext;
|
||||
use Carbon\Carbon;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
use Request;
|
||||
@ -78,11 +79,7 @@ class WebSocketDialogMsgTask extends AbstractTask
|
||||
|
||||
public function start()
|
||||
{
|
||||
global $_A;
|
||||
$_A = [
|
||||
'__fill_url_remote_url' => true,
|
||||
];
|
||||
|
||||
RequestContext::set('fill_url_remote_url', true);
|
||||
//
|
||||
$msg = WebSocketDialogMsg::find($this->id);
|
||||
if (empty($msg)) {
|
||||
|
||||
@ -134,7 +134,6 @@ return [
|
||||
*/
|
||||
|
||||
'event_handlers' => [
|
||||
'ServerStart' => \App\Events\ServerStartEvent::class,
|
||||
'WorkerStart' => \App\Events\WorkerStartEvent::class,
|
||||
],
|
||||
|
||||
@ -222,7 +221,38 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'swoole_tables' => [],
|
||||
'swoole_tables' => [
|
||||
'initFlag' => [
|
||||
'size' => 1,
|
||||
'column' => [
|
||||
[
|
||||
'name' => 'value',
|
||||
'type' => \Swoole\Table::TYPE_INT,
|
||||
'size' => 8
|
||||
],
|
||||
],
|
||||
],
|
||||
'globalData' => [
|
||||
'size' => 1024,
|
||||
'column' => [
|
||||
[
|
||||
'name' => 'value',
|
||||
'type' => \Swoole\Table::TYPE_STRING,
|
||||
'size' => 1024
|
||||
],
|
||||
],
|
||||
],
|
||||
'onlineData' => [
|
||||
'size' => 10240,
|
||||
'column' => [
|
||||
[
|
||||
'name' => 'value',
|
||||
'type' => \Swoole\Table::TYPE_INT,
|
||||
'size' => 8
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user