侧边栏壁纸
  • 累计撰写 26 篇文章
  • 累计创建 35 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

定制Halo的Read实现

Honesty
2020-07-21 / 0 评论 / 0 点赞 / 189 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-12-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

上篇文章介绍了Read的使用与实现。但在整合到Halo的之前的实现就感觉有点不太适用故新增一个基于AbstractStringCacheStore来实现一个Read

代码实现

/**
 * @author: HeHui
 * @date: 2020-07-21 11:05
 * @description: 本地缓存阅读
 */
@Slf4j
public class LocalCacheRead<POST extends BasePost> extends ReadAbstract<Double,Integer> {


    private final AbstractStringCacheStore stringCacheStore;

    private final String cacheKey;


    /**
     * 本地缓存读
     *
     * @param maxRead          最大阅读数
     * @param jobSeconds       工定时秒
     * @param stringCacheStore 字符串数据缓存
     * @param basePostService  基地发布服务
     * @param cacheKey         缓存键
     */
    public LocalCacheRead(Double maxRead, int jobSeconds, AbstractStringCacheStore stringCacheStore,BasePostService basePostService,String cacheKey) {
        super(maxRead, jobSeconds, new VisitReadStorage(basePostService,cacheKey));
        this.cacheKey = cacheKey;
        this.stringCacheStore = stringCacheStore;
    }






    /**
     * 增加
     *
     * @param id         id
     * @param readNumber 阅读数量
     * @return {@link Optional<Double>}
     */
    @Override
    protected Optional<Double> increase(Integer id, Double readNumber) {
        Map<Integer, Double> cache = getCache();
        if(cache == null){
            cache = new HashMap<>(128);
        }
        Double aDouble = cache.getOrDefault(id,0D);
        cache.put(id,aDouble + readNumber);

        stringCacheStore.putAny(cacheKey,cache);

        return Optional.ofNullable(aDouble + readNumber);
    }




    /**
     * 减少
     *
     * @param id         id
     * @param readNumber 阅读数量
     */
    @Override
    protected void reduce(Integer id, Double readNumber) {
        Map<Integer, Double> cache = getCache();
        if(MapUtil.isNotEmpty(cache)){
            Double aDouble = cache.get(id);
            if(aDouble == null || aDouble <= readNumber){
                cache.remove(id);
            }else{
                cache.put(id,aDouble - readNumber);
            }

           stringCacheStore.putAny(cacheKey,cache);
        }
    }



    /**
     * 得到所有
     *
     * @return {@link Optional<Map<Integer, Double>>}
     */
    @Override
    protected Optional<Map<Integer, Double>> getAll() {
        return Optional.ofNullable(getCache());
    }

    /**
     * 清除
     */
    @Override
    protected void clear() {
        stringCacheStore.delete(cacheKey);
    }

    /**
     * 清除
     *
     * @param id id
     * @return {@link Optional<Double>}
     */
    @Override
    public Optional<Double> getRead(Integer id) {
        Map<Integer, Double> cache = getCache();
        if(MapUtil.isNotEmpty(cache)){
            return Optional.ofNullable(cache.get(id));
        }
        return Optional.empty();
    }



    /**
     *  查询指定
     * @param ids
     * @return {@link Optional<Map<Integer, Double>>}
     */
    @Override
    public Optional<Map<Integer, Double>> getReads(List<Integer> ids) {
        Map<Integer, Double> map = getCache();
        if(MapUtil.isNotEmpty(map)){
            Optional.ofNullable(map.entrySet().stream().filter(v->ids.contains(v.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
        }
        return Optional.empty();
    }






    /**
     *  查询缓存
     * @return
     */
    private Map<Integer, Double> getCache(){
        Optional<Map> optional = stringCacheStore.getAny(cacheKey, Map.class);
        if(optional.isPresent()){
            /**
             *  key适用String 是因为在测试过程中发现 getAny 转换的key就是String 如果声明Integer在获取时就会报错
             */
            Map<String,Double> map = optional.get();
            return map.entrySet().stream().collect(Collectors.toMap(v->Integer.valueOf(v.getKey()), Map.Entry::getValue));
        }
        return null;
    }






    /**
     *  阅读数存储
     */
    static class VisitReadStorage implements ReadStorage<Double,Integer>{
        private BasePostService postService;
        private String name;

        VisitReadStorage(BasePostService basePostService,String name){
            this.postService = basePostService;
            this.name = name;
        }



        @Override
        public void increase(Integer posId, Double n) {
            postService.increaseVisit(n.longValue(),posId);
            log.info("{} 新增阅读数:{},postId:{}",name,n,posId);

        }

        @Override
        public void increase(Map<Integer, Double> map) {
            log.info("{}: 定时清除阅读数",name);
            try {
                postService.increaseListVisit(map);
            }catch (Exception e){
                log.error("{} 定时清除阅读数异常:", name,e);
            }
        }
    }

}

配置

特别注意:cahceKey不要重复,此处的参数可改为配置的

/**
     *  post 阅读器缓存
     * @param stringCacheStore
     * @param postService
     * @return
     */
    @Bean
    @Primary
    public LocalCacheRead<Post> postLocalCacheRead(AbstractStringCacheStore stringCacheStore, PostService postService){
        return new LocalCacheRead<Post>(35D,300,stringCacheStore,postService,"post:read:cache" );
    }

    /**
     *  Sheet 阅读器缓存
     * @param stringCacheStore
     * @param sheetService
     * @return
     */
    @Bean
    public LocalCacheRead<Sheet> sheetLocalCacheRead(AbstractStringCacheStore stringCacheStore, SheetService sheetService){
        return new LocalCacheRead<Sheet>(12D,300,stringCacheStore,sheetService,"sheet:read:cache" );
    }

使用

/**
 * Visit event listener.
 *
 * @author johnniang
 * @date 19-4-22
 */
@Component
public class PostVisitEventListener extends AbstractSmoothVisitEventListener<Post> {

    public PostVisitEventListener(run.halo.app.core.LocalCacheRead<Post> read) {
        super(read);
    }


    @Async
    @EventListener
    public void onPostVisitEvent(PostVisitEvent event) throws InterruptedException {
        handleVisitEvent(event);
    }
}

实时显示最新阅读数

实时显示最新阅读数只需要在需要显示最新阅读数的代码中加上就好Read提供Optional getRead(ID key)和Optional<Map<ID,T>> getReads(List keys)

目前需要加的地方有

  1. PostController#pageBy
  2. PostController#pageByStatus
  3. PostModel#content
  4. PostModel#list
0

评论区