利用本地缓存实现跑马灯记录

64 阅读1分钟
/**
 * 跑马灯记录查询接口
 */
@Component
public class MarqueeRecordAction implements Action {
    @Autowired
    private Service service;
    @Autowired
    LocalCacheManager localCacheManager;
    private static final Logger log = LoggerFactory.getLogger(MarqueeRecordAction.class);
    private static final String ACTION_NAME = "marqueeRecord";
    private static final String LOTTERY_RECORD_KEY = "lotteryRecord";
    @Override
    public String actionName() {
        return ACTION_NAME;
    }
    @Override
    public Object execute(BrandLinkageContext ctx) throws Exception {
        MarqueeRecordsVO result = new MarqueeRecordsVO();
        long userId = ctx.getUserId();
        List<String> strategyCodes = new ArrayList<>(BenefitInfoProcessUtil.allLotteryStrategyCodes());
        // 先从本地缓存获取,每次更新后x分钟失效
        Optional<List<MarqueeRecordVO>> records = localCacheManager.getMarqueeRecord(LOTTERY_RECORD_KEY);
        if (Objects.nonNull(records)) {
            List<MarqueeRecordVO> marqueeRecords = records.orElse(null);
            result.setMarqueeRecords(marqueeRecords);
            return result;
        }
        // 本地缓存无数据,请求拉菲获取跑马灯记录
        List<MarqueeWinRecordDTO> marqueeWinRecords = service.listMarqueeRecord(strategyCodes);
        if (CollectionUtils.isEmpty(marqueeWinRecords)) {
            log.error("MARQUEE_RECORD_IS_EMPTY, strategyCodes={}", JSON.toJSONString(strategyCodes));
            localCacheManager.updateMarqueeRecord(LOTTERY_RECORD_KEY, Optional.empty());
            return null;
        }
        List<MarqueeRecordVO> newRecords = marqueeWinRecords.stream()
            .filter(record -> Objects.nonNull(record) && Objects.nonNull(record.getUserNick()) && Objects.nonNull(record.getBenefitTitle()))
            .map(this::convert2MarqueeRecordVO)
            .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(newRecords)) {
            log.error("MARQUEE_RECORD_AVAILABLE_IS_EMPTY, strategyCodes={}", JSON.toJSONString(strategyCodes));
            localCacheManager.updateMarqueeRecord(LOTTERY_RECORD_KEY, Optional.empty());
            return null;
        }
        localCacheManager.updateMarqueeRecord(LOTTERY_RECORD_KEY, Optional.of(newRecords));
        result.setMarqueeRecords(newRecords);
        // 调用埋点
        
        return result;
    }
    private MarqueeRecordVO convert2MarqueeRecordVO(MarqueeWinRecordDTO winRecord) {
        MarqueeRecordVO recordVO = new MarqueeRecordVO();
        // 昵称匿名化处理
        recordVO.setUserNick(BenefitInfoProcessUtil.anonymizeUserNick(winRecord.getUserNick()));
        recordVO.setTitle(winRecord.getBenefitTitle());
        return recordVO;
    }
}
/**
 * 本地缓存管理类
 */
@Component
public class LocalCacheManager {
    private static final Cache<String, Optional<List<MarqueeRecordVO>>> MARQUEE_CACHE = CacheBuilder.newBuilder()
        .initialCapacity(10)
        .maximumSize(100)
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .build();
    /**
     * 获取跑马灯缓存
     * @param key 键
     * @return 跑马灯记录
     */
    public Optional<List<MarqueeRecordVO>> getMarqueeRecord(String key) {
        return MARQUEE_CACHE.getIfPresent(key);
    }
    /**
     * 更新跑马灯缓存
     * @param key 键
     * @param value 跑马灯记录
     */
    public void updateMarqueeRecord(String key, Optional<List<MarqueeRecordVO>> value) {
        MARQUEE_CACHE.put(key, value);
    }
}