token permission cache load from db when not exists

This commit is contained in:
xiaomlove
2025-12-30 12:56:56 +07:00
parent eb248110fc
commit 791c617bc0
2 changed files with 41 additions and 8 deletions
+16 -6
View File
@@ -82,13 +82,23 @@ class TrackerUrl extends NexusModel
if ($redis->exists($notFoundFlagKey)) { if ($redis->exists($notFoundFlagKey)) {
return false; return false;
} }
self::saveUrlCache(); $lockKey = "$notFoundFlagKey:lock";
$result = call_user_func_array([$redis, $command], $params); if (!$redis->set($lockKey, 1, ["nx", "ex" => 5])) {
if ($result !== false) { return false;
return $result; }
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'); do_log(sprintf("redis command %s with args %s no result", $command, json_encode($params)), 'error');
return false; return false;
} }
+25 -2
View File
@@ -5,6 +5,7 @@ namespace App\Models;
use App\Exceptions\NexusException; use App\Exceptions\NexusException;
use App\Http\Middleware\Locale; use App\Http\Middleware\Locale;
use App\Repositories\ExamRepository; use App\Repositories\ExamRepository;
use App\Repositories\TokenRepository;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute; 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}]"); 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(); $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); && $this->accessToken && $this->accessToken->can($ability);
} }