From 791c617bc0b721c18506ca93b86cf8d3673ca8f2 Mon Sep 17 00:00:00 2001 From: xiaomlove <1939737565@qq.com> Date: Tue, 30 Dec 2025 12:56:56 +0700 Subject: [PATCH] token permission cache load from db when not exists --- app/Models/TrackerUrl.php | 22 ++++++++++++++++------ app/Models/User.php | 27 +++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/Models/TrackerUrl.php b/app/Models/TrackerUrl.php index 9d5f7c4c..b2afbf75 100644 --- a/app/Models/TrackerUrl.php +++ b/app/Models/TrackerUrl.php @@ -82,13 +82,23 @@ class TrackerUrl extends NexusModel if ($redis->exists($notFoundFlagKey)) { return false; } - self::saveUrlCache(); - $result = call_user_func_array([$redis, $command], $params); - if ($result !== false) { - return $result; + $lockKey = "$notFoundFlagKey:lock"; + if (!$redis->set($lockKey, 1, ["nx", "ex" => 5])) { + return false; + } + try { + self::saveUrlCache(); + $result = call_user_func_array([$redis, $command], $params); + if ($result !== false) { + return $result; + } + //只从 db 拉取一次,仍然没有即标记不存在, 有效期 15 分钟 + $redis->setex($notFoundFlagKey, 900, date("Y-m-d H:i:s")); + } catch (\Throwable $throwable) { + do_log($throwable->getMessage(), 'error'); + } finally { + $redis->del($lockKey); } - //只从 db 拉取一次,仍然没有即标记不存在, 有效期 15 分钟 - $redis->setex($notFoundFlagKey, 900, date("Y-m-d H:i:s")); do_log(sprintf("redis command %s with args %s no result", $command, json_encode($params)), 'error'); return false; } diff --git a/app/Models/User.php b/app/Models/User.php index f311115e..a07b5c8b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,6 +5,7 @@ namespace App\Models; use App\Exceptions\NexusException; use App\Http\Middleware\Locale; use App\Repositories\ExamRepository; +use App\Repositories\TokenRepository; use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; @@ -626,10 +627,32 @@ class User extends Authenticatable implements FilamentUser, HasName return is_null($this->original['notifs']) || str_contains($this->notifs, "[{$name}]"); } - public function tokenCan(string $ability) + public function tokenCan(string $ability): bool { $redis = NexusDB::redis(); - return $redis->sismember(Setting::USER_TOKEN_PERMISSION_ALLOWED_CACHE_KRY, $ability) + $cacheKey = Setting::USER_TOKEN_PERMISSION_ALLOWED_CACHE_KRY; + if (!$redis->exists($cacheKey)) { + $lockKey = "$cacheKey:lock"; + if ($redis->set($lockKey, 1, ['nx', 'ex' => 5])) { + try { + if (!$redis->exists($cacheKey)) { + $abilities = TokenRepository::listUserTokenPermissions(false); + do_log("load user token permissions: " . json_encode($abilities), 'alert'); + if (!empty($abilities)) { + $redis->sadd($cacheKey, ...$abilities); + } else { + $redis->sadd($cacheKey, "__NO_USER_TOKEN_PERMISSION__"); + $redis->expire($cacheKey, 900); + } + } + } catch (\Throwable $throwable) { + do_log($throwable->getMessage(), 'error'); + } finally { + $redis->del($lockKey); + } + } + } + return $redis->sismember($cacheKey, $ability) && $this->accessToken && $this->accessToken->can($ability); }