mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-07-01 12:57:26 +00:00
[Add] AutoCleanTimer, Cleanable 增加缓存库自动清理;
[Update] HotDataCacheStore 增加对自动清理的支持; [Change] RedisPoolCacheStore 将Redis缓存库抽象类设为default(原public); [Change] MiraiMessageSender, BotCommandProcess 适配HotDataCacheStore的修改; [Change] BotCommandProcess 调整ranking命令的输出格式;
This commit is contained in:
@ -50,7 +50,7 @@ public class BotCommandProcess {
|
||||
private final static CacheStore<JsonElement> illustInfoCache = new JsonRedisCacheStore(BotEventHandler.redisServer, "illustInfo", gson);
|
||||
private final static CacheStore<JsonElement> illustPreLoadDataCache = new HotDataCacheStore<>(
|
||||
new JsonRedisCacheStore(BotEventHandler.redisServer, "illustPreLoadData", gson),
|
||||
new LocalHashCacheStore<>(), 3600000, 900000);
|
||||
new LocalHashCacheStore<>(), 3600000, 900000, true);
|
||||
private final static CacheStore<JsonElement> searchBodyCache = new JsonRedisCacheStore(BotEventHandler.redisServer, "searchBody", gson);
|
||||
private final static CacheStore<List<JsonObject>> rankingCache = new JsonObjectRedisListCacheStore(BotEventHandler.redisServer, "ranking", gson);
|
||||
private final static CacheStore<List<String>> pagesCache = new StringListRedisCacheStore(BotEventHandler.redisServer, "imagePages");
|
||||
@ -408,7 +408,7 @@ public class BotCommandProcess {
|
||||
StringBuilder builder = new StringBuilder("[");
|
||||
illustObj.get("tags").getAsJsonArray().forEach(el -> builder.append(el.getAsString()).append(", "));
|
||||
builder.replace(builder.length() - 2, builder.length(), "]");
|
||||
log.debug("{} ({} / {})\n\t作品id: {}, \n\t作者名(作者id): {} ({}), \n\t作品标题: {}, \n\t作品Tags: {}, \n\t页数: {}, \n\t作品链接: {}",
|
||||
log.debug("{} ({} / {})\n\t作品id: {}, \n\t作者名(作者id): {} ({}), \n\t作品标题: {}, \n\t作品Tags: {}, \n\t页数: {}页, \n\t作品链接: {}",
|
||||
searchArea.name(),
|
||||
count,
|
||||
illustsList.size(),
|
||||
@ -435,7 +435,7 @@ public class BotCommandProcess {
|
||||
result.append(searchArea.name()).append(" (").append(count).append(" / ").append(limit).append(")\n\t作品id: ").append(illustId)
|
||||
.append(", \n\t作者名: ").append(illustObj.get("userName").getAsString())
|
||||
.append("\n\t作品标题: ").append(illustObj.get("illustTitle").getAsString())
|
||||
.append("\n\t作品页数: ").append(illustObj.get("pageCount").getAsInt())
|
||||
.append("\n\t作品页数: ").append(illustObj.get("pageCount").getAsInt()).append("页")
|
||||
.append("\n").append(imageMsg).append("\n");
|
||||
count++;
|
||||
}
|
||||
|
52
src/main/java/net/lamgc/cgj/bot/cache/AutoCleanTimer.java
vendored
Normal file
52
src/main/java/net/lamgc/cgj/bot/cache/AutoCleanTimer.java
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
package net.lamgc.cgj.bot.cache;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class AutoCleanTimer extends TimerTask {
|
||||
|
||||
private final static Set<Cleanable> cleanSet = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final static Timer cleanTimer = new Timer("Thread-AutoClean", true);
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(AutoCleanTimer.class.getName());
|
||||
|
||||
static {
|
||||
cleanTimer.schedule(new AutoCleanTimer(), 100L);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加需要定时执行清理的缓存库
|
||||
* @param store 已实现Cleanable的对象
|
||||
*/
|
||||
public static void add(Cleanable store) {
|
||||
cleanSet.add(store);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除已添加的缓存库
|
||||
* @param store 需要从AutoCleanTimer移除的对象
|
||||
*/
|
||||
public static void remove(Cleanable store) {
|
||||
cleanSet.remove(store);
|
||||
}
|
||||
|
||||
private AutoCleanTimer() {}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
cleanSet.forEach(cleanable -> {
|
||||
try {
|
||||
cleanable.clean();
|
||||
} catch (Exception e) {
|
||||
log.error("{} 执行清理动作时发生异常:\n{}", cleanable.toString(), Throwables.getStackTraceAsString(e));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
10
src/main/java/net/lamgc/cgj/bot/cache/Cleanable.java
vendored
Normal file
10
src/main/java/net/lamgc/cgj/bot/cache/Cleanable.java
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package net.lamgc.cgj.bot.cache;
|
||||
|
||||
/**
|
||||
* 可清理接口, 实现该接口代表该类拥有清理动作.
|
||||
*/
|
||||
public interface Cleanable {
|
||||
|
||||
void clean() throws Exception;
|
||||
|
||||
}
|
@ -10,7 +10,7 @@ import java.util.*;
|
||||
* @param <T> 存储类型
|
||||
* @author LamGC
|
||||
*/
|
||||
public class HotDataCacheStore<T> implements CacheStore<T> {
|
||||
public class HotDataCacheStore<T> implements CacheStore<T>, Cleanable {
|
||||
|
||||
private final CacheStore<T> parent;
|
||||
private final CacheStore<T> current;
|
||||
@ -24,17 +24,22 @@ public class HotDataCacheStore<T> implements CacheStore<T> {
|
||||
* @param parent 上级缓存存储库
|
||||
* @param current 热点缓存存储库, 最好使用本地缓存(例如 {@linkplain LocalHashCacheStore LocalHashCacheStore})
|
||||
* @param expireTime 本地缓存库的缓存项过期时间, 单位毫秒;
|
||||
* 该时间并不是所有缓存项的最终过期时间, 还需要根据expireFloatRange的设定随机设置, 公式:
|
||||
* {@code expireTime + new Random().nextInt(expireFloatRange)}
|
||||
* 该时间并不是所有缓存项的最终过期时间, 还需要根据expireFloatRange的设定随机设置, 公式:
|
||||
* {@code expireTime + new Random().nextInt(expireFloatRange)}
|
||||
* @param expireFloatRange 过期时间的浮动范围(单位毫秒), 用于防止短时间内大量缓存项失效导致的缓存雪崩
|
||||
* @param autoClean 是否交由{@link AutoCleanTimer}自动执行清理
|
||||
*/
|
||||
public HotDataCacheStore(CacheStore<T> parent, CacheStore<T> current, long expireTime, int expireFloatRange) {
|
||||
public HotDataCacheStore(CacheStore<T> parent, CacheStore<T> current, long expireTime, int expireFloatRange, boolean autoClean) {
|
||||
this.parent = parent;
|
||||
this.current = current;
|
||||
this.expireTime = expireTime;
|
||||
this.expireFloatRange = expireFloatRange;
|
||||
log.debug("HotDataCacheStore初始化完成. (Parent: {}, Current: {}, expireTime: {}, expireFloatRange: {})",
|
||||
parent, current, expireTime, expireFloatRange);
|
||||
if(autoClean) {
|
||||
AutoCleanTimer.add(this);
|
||||
}
|
||||
|
||||
log.debug("HotDataCacheStore初始化完成. (Parent: {}, Current: {}, expireTime: {}, expireFloatRange: {}, autoClean: {})",
|
||||
parent, current, expireTime, expireFloatRange, autoClean);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,4 +126,13 @@ public class HotDataCacheStore<T> implements CacheStore<T> {
|
||||
public boolean supportedList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean() {
|
||||
for(String key : this.current.keys()) {
|
||||
if(current.exists(key)) {
|
||||
current.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class RedisPoolCacheStore<T> implements CacheStore<T> {
|
||||
abstract class RedisPoolCacheStore<T> implements CacheStore<T> {
|
||||
|
||||
private final JedisPool jedisPool;
|
||||
private final String keyPrefix;
|
||||
|
@ -33,7 +33,7 @@ public class MiraiMessageSender implements MessageSender {
|
||||
private final static CacheStore<String> imageIdCache = new HotDataCacheStore<>(
|
||||
new StringRedisCacheStore(BotEventHandler.redisServer, "mirai.imageId"),
|
||||
new LocalHashCacheStore<>(),
|
||||
5400000, 1800000);
|
||||
5400000, 1800000, true);
|
||||
|
||||
/**
|
||||
* 使用id构造发送器
|
||||
|
Reference in New Issue
Block a user