Skip to content

Commit

Permalink
bugfix:async Cache 导致租户不正确的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
YunaiV committed Feb 27, 2024
1 parent 8537964 commit 5be7965
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package cn.iocoder.yudao.framework.common.util.cache;

import com.alibaba.ttl.threadpool.TtlExecutors;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.time.Duration;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
Expand All @@ -16,14 +14,36 @@
*/
public class CacheUtils {

/**
* 构建异步刷新的 LoadingCache 对象
*
* 注意:如果你的缓存和 ThreadLocal 有关系,要么自己处理 ThreadLocal 的传递,要么使用 {@link #buildCache(Duration, CacheLoader)} 方法
*
* 或者简单理解:
* 1、和“人”相关的,使用 {@link #buildCache(Duration, CacheLoader)} 方法
* 2、和“全局”、“系统”相关的,使用当前缓存方法
*
* @param duration 过期时间
* @param loader CacheLoader 对象
* @return LoadingCache 对象
*/
public static <K, V> LoadingCache<K, V> buildAsyncReloadingCache(Duration duration, CacheLoader<K, V> loader) {
Executor executor = Executors.newCachedThreadPool( // TODO 芋艿:可能要思考下,未来要不要做成可配置
TtlExecutors.getDefaultDisableInheritableThreadFactory()); // TTL 保证 ThreadLocal 可以透传
return CacheBuilder.newBuilder()
// 只阻塞当前数据加载线程,其他线程返回旧值
.refreshAfterWrite(duration)
// 通过 asyncReloading 实现全异步加载,包括 refreshAfterWrite 被阻塞的加载线程
.build(CacheLoader.asyncReloading(loader, executor));
.build(CacheLoader.asyncReloading(loader, Executors.newCachedThreadPool())); // TODO 芋艿:可能要思考下,未来要不要做成可配置
}

/**
* 构建同步刷新的 LoadingCache 对象
*
* @param duration 过期时间
* @param loader CacheLoader 对象
* @return LoadingCache 对象
*/
public static <K, V> LoadingCache<K, V> buildCache(Duration duration, CacheLoader<K, V> loader) {
return CacheBuilder.newBuilder().refreshAfterWrite(duration).build(loader);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import java.time.Duration;

import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;

/**
* 字典工具类
*
Expand All @@ -27,7 +29,7 @@ public class DictFrameworkUtils {
/**
* 针对 {@link #getDictDataLabel(String, String)} 的缓存
*/
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> GET_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> GET_DICT_DATA_CACHE = buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {

Expand All @@ -42,7 +44,7 @@ public DictDataRespDTO load(KeyValue<String, String> key) {
/**
* 针对 {@link #parseDictDataValue(String, String)} 的缓存
*/
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> PARSE_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> PARSE_DICT_DATA_CACHE = buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.time.Duration;
import java.util.List;

import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;

/**
* Tenant 框架 Service 实现类
*
Expand All @@ -24,7 +26,7 @@ public class TenantFrameworkServiceImpl implements TenantFrameworkService {
/**
* 针对 {@link #getTenantIds()} 的缓存
*/
private final LoadingCache<Object, List<Long>> getTenantIdsCache = CacheUtils.buildAsyncReloadingCache(
private final LoadingCache<Object, List<Long>> getTenantIdsCache = buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<Object, List<Long>>() {

Expand All @@ -38,7 +40,7 @@ public List<Long> load(Object key) {
/**
* 针对 {@link #validTenant(Long)} 的缓存
*/
private final LoadingCache<Long, CommonResult<Boolean>> validTenantCache = CacheUtils.buildAsyncReloadingCache(
private final LoadingCache<Long, CommonResult<Boolean>> validTenantCache = buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<Long, CommonResult<Boolean>>() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.util.Arrays;
import java.util.List;

import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
Expand All @@ -35,7 +37,7 @@ public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
/**
* 针对 {@link #hasAnyRoles(String...)} 的缓存
*/
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyRolesCache = CacheUtils.buildAsyncReloadingCache(
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyRolesCache = buildCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<Long, List<String>>, Boolean>() {

Expand All @@ -49,7 +51,7 @@ public Boolean load(KeyValue<Long, List<String>> key) {
/**
* 针对 {@link #hasAnyPermissions(String...)} 的缓存
*/
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyPermissionsCache = CacheUtils.buildAsyncReloadingCache(
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyPermissionsCache = buildCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<Long, List<String>>, Boolean>() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import java.util.Objects;
import java.util.function.Function;

import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;

/**
* Token 过滤器,验证 token 的有效性
* 1. 验证通过时,将 userId、userType、tenantId 通过 Header 转发给服务
Expand Down Expand Up @@ -59,7 +62,7 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
* key1:多租户的编号
* key2:访问令牌
*/
private final LoadingCache<KeyValue<Long, String>, LoginUser> loginUserCache = CacheUtils.buildAsyncReloadingCache(Duration.ofMinutes(1),
private final LoadingCache<KeyValue<Long, String>, LoginUser> loginUserCache = buildAsyncReloadingCache(Duration.ofMinutes(1),
new CacheLoader<KeyValue<Long, String>, LoginUser>() {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;

@Tag(name = "用户 App - 砍价活动")
Expand All @@ -42,7 +43,7 @@ public class AppBargainActivityController {
/**
* {@link AppBargainActivityRespVO} 缓存,通过它异步刷新 {@link #getBargainActivityList0(Integer)} 所要的首页数据
*/
private final LoadingCache<Integer, List<AppBargainActivityRespVO>> bargainActivityListCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
private final LoadingCache<Integer, List<AppBargainActivityRespVO>> bargainActivityListCache = buildCache(Duration.ofSeconds(10L),
new CacheLoader<Integer, List<AppBargainActivityRespVO>>() {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;

@Tag(name = "用户 APP - 拼团活动")
Expand All @@ -43,7 +44,7 @@ public class AppCombinationActivityController {
/**
* {@link AppCombinationActivityRespVO} 缓存,通过它异步刷新 {@link #getCombinationActivityList0(Integer)} 所要的首页数据
*/
private final LoadingCache<Integer, List<AppCombinationActivityRespVO>> combinationActivityListCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
private final LoadingCache<Integer, List<AppCombinationActivityRespVO>> combinationActivityListCache = buildCache(Duration.ofSeconds(10L),
new CacheLoader<Integer, List<AppCombinationActivityRespVO>>() {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildCache;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween;
Expand All @@ -52,7 +53,7 @@ public class AppSeckillActivityController {
/**
* {@link AppSeckillActivityNowRespVO} 缓存,通过它异步刷新 {@link #getNowSeckillActivity()} 所要的首页数据
*/
private final LoadingCache<String, AppSeckillActivityNowRespVO> nowSeckillActivityCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
private final LoadingCache<String, AppSeckillActivityNowRespVO> nowSeckillActivityCache = buildCache(Duration.ofSeconds(10L),
new CacheLoader<String, AppSeckillActivityNowRespVO>() {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

Expand Down Expand Up @@ -75,7 +76,7 @@ public class SocialClientServiceImpl implements SocialClientService {
*
* 为什么要做 WxMpService 缓存?因为 WxMpService 构建成本比较大,所以尽量保证它是单例。
*/
private final LoadingCache<String, WxMpService> wxMpServiceCache = CacheUtils.buildAsyncReloadingCache(
private final LoadingCache<String, WxMpService> wxMpServiceCache = buildAsyncReloadingCache(
Duration.ofSeconds(10L),
new CacheLoader<String, WxMpService>() {

Expand All @@ -96,7 +97,7 @@ public WxMpService load(String key) {
*
* 说明同 {@link #wxMpServiceCache} 变量
*/
private final LoadingCache<String, WxMaService> wxMaServiceCache = CacheUtils.buildAsyncReloadingCache(
private final LoadingCache<String, WxMaService> wxMaServiceCache = buildAsyncReloadingCache(
Duration.ofSeconds(10L),
new CacheLoader<String, WxMaService>() {

Expand Down

0 comments on commit 5be7965

Please sign in to comment.