This commit is contained in:
redkale
2023-12-11 23:41:57 +08:00
parent f7e3f7d7ec
commit 618a42c5df
5 changed files with 227 additions and 73 deletions

View File

@@ -25,7 +25,7 @@ module org.redkale {
exports org.redkale.convert.ext;
exports org.redkale.convert.json;
exports org.redkale.convert.protobuf;
exports org.redkale.locking;
exports org.redkale.lock;
exports org.redkale.mq;
exports org.redkale.net;
exports org.redkale.net.client;

View File

@@ -6,6 +6,7 @@ package org.redkale.cache;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
/**
* 缓存管理器
@@ -24,296 +25,324 @@ public interface CacheManager {
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T localGet(final String map, final String key, final Type type);
public <T> T localGet(final String hash, final String key, final Type type);
/**
* 本地获取字符串缓存数据, 过期返回null
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default String localGetString(final String map, final String key) {
return localGet(map, key, String.class);
default String localGetString(final String hash, final String key) {
return localGet(hash, key, String.class);
}
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param expire 过期时长为null表示永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
public <T> T localGet(final String hash, final String key, final Type type, Duration expire, Supplier<T> supplier);
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param expire 过期时长为null表示永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
public <T> CompletableFuture<T> localGetAsync(String hash, String key, Type type, Duration expire, Supplier<CompletableFuture<T>> supplier);
/**
* 本地缓存数据
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长为null表示永不过期
*/
public <T> void localSet(String map, String key, Type type, T value, Duration expire);
public <T> void localSet(String hash, String key, Type type, T value, Duration expire);
/**
* 本地缓存字符串数据
*
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长为null表示永不过期
*/
default void localSetString(final String map, final String key, final String value, Duration expire) {
localSet(map, key, String.class, value, expire);
default void localSetString(final String hash, final String key, final String value, Duration expire) {
localSet(hash, key, String.class, value, expire);
}
/**
* 本地删除缓存数据
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public long localDel(String map, String key);
public long localDel(String hash, String key);
//-------------------------------------- 远程缓存 --------------------------------------
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T remoteGet(final String map, final String key, final Type type);
public <T> T remoteGet(final String hash, final String key, final Type type);
/**
* 远程获取字符串缓存数据, 过期返回null
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default String remoteGetString(final String map, final String key) {
return remoteGet(map, key, String.class);
default String remoteGetString(final String hash, final String key) {
return remoteGet(hash, key, String.class);
}
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> CompletableFuture<T> remoteGetAsync(final String map, final String key, final Type type);
public <T> CompletableFuture<T> remoteGetAsync(final String hash, final String key, final Type type);
/**
* 远程异步获取字符串缓存数据, 过期返回null
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default CompletableFuture<String> remoteGetStringAsync(final String map, final String key) {
return remoteGetAsync(map, key, String.class);
default CompletableFuture<String> remoteGetStringAsync(final String hash, final String key) {
return remoteGetAsync(hash, key, String.class);
}
/**
* 远程缓存数据
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长为null表示永不过期
*/
public <T> void remoteSet(final String map, final String key, final Type type, final T value, Duration expire);
public <T> void remoteSet(final String hash, final String key, final Type type, final T value, Duration expire);
/**
* 远程缓存字符串数据
*
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长为null表示永不过期
*/
default void remoteSetString(final String map, final String key, final String value, Duration expire) {
remoteSet(map, key, String.class, value, expire);
default void remoteSetString(final String hash, final String key, final String value, Duration expire) {
remoteSet(hash, key, String.class, value, expire);
}
/**
* 远程异步缓存数据
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长为null表示永不过期
*/
public <T> CompletableFuture<Void> remoteSetAsync(String map, String key, Type type, T value, Duration expire);
public <T> CompletableFuture<Void> remoteSetAsync(String hash, String key, Type type, T value, Duration expire);
/**
* 远程异步缓存字符串数据
*
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长为null表示永不过期
*/
default CompletableFuture<Void> remoteSetStringAsync(final String map, final String key, final String value, Duration expire) {
return remoteSetAsync(map, key, String.class, value, expire);
default CompletableFuture<Void> remoteSetStringAsync(final String hash, final String key, final String value, Duration expire) {
return remoteSetAsync(hash, key, String.class, value, expire);
}
/**
* 远程删除缓存数据
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public long remoteDel(String map, String key);
public long remoteDel(String hash, String key);
/**
* 远程异步删除缓存数据
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public CompletableFuture<Long> remoteDelAsync(String map, String key);
public CompletableFuture<Long> remoteDelAsync(String hash, String key);
//-------------------------------------- both缓存 --------------------------------------
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T bothGet(final String map, final String key, final Type type);
public <T> T bothGet(final String hash, final String key, final Type type);
/**
* 远程获取字符串缓存数据, 过期返回null
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default String bothGetString(final String map, final String key) {
return bothGet(map, key, String.class);
default String bothGetString(final String hash, final String key) {
return bothGet(hash, key, String.class);
}
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> CompletableFuture<T> bothGetAsync(final String map, final String key, final Type type);
public <T> CompletableFuture<T> bothGetAsync(final String hash, final String key, final Type type);
/**
* 远程异步获取字符串缓存数据, 过期返回null
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default CompletableFuture<String> bothGetStringAsync(final String map, final String key) {
return bothGetAsync(map, key, String.class);
default CompletableFuture<String> bothGetStringAsync(final String hash, final String key) {
return bothGetAsync(hash, key, String.class);
}
/**
* 远程缓存数据
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长为null表示永不过期
* @param remoteExpire 远程过期时长为null表示永不过期
*/
public <T> void bothSet(final String map, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire);
public <T> void bothSet(final String hash, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire);
/**
* 远程缓存字符串数据
*
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长为null表示永不过期
* @param remoteExpire 远程过期时长为null表示永不过期
*/
default void bothSetString(final String map, final String key, final String value, Duration localExpire, Duration remoteExpire) {
bothSet(map, key, String.class, value, localExpire, remoteExpire);
default void bothSetString(final String hash, final String key, final String value, Duration localExpire, Duration remoteExpire) {
bothSet(hash, key, String.class, value, localExpire, remoteExpire);
}
/**
* 远程异步缓存数据
*
* @param <T> 泛型
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长为null表示永不过期
* @param remoteExpire 远程过期时长为null表示永不过期
*/
public <T> CompletableFuture<Void> bothSetAsync(String map, String key, Type type, T value, Duration localExpire, Duration remoteExpire);
public <T> CompletableFuture<Void> bothSetAsync(String hash, String key, Type type, T value, Duration localExpire, Duration remoteExpire);
/**
* 远程异步缓存字符串数据
*
* @param map 缓存hash
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长为null表示永不过期
* @param remoteExpire 远程过期时长为null表示永不过期
*/
default CompletableFuture<Void> bothSetStringAsync(String map, String key, String value, Duration localExpire, Duration remoteExpire) {
return bothSetAsync(map, key, String.class, value, localExpire, remoteExpire);
default CompletableFuture<Void> bothSetStringAsync(String hash, String key, String value, Duration localExpire, Duration remoteExpire) {
return bothSetAsync(hash, key, String.class, value, localExpire, remoteExpire);
}
/**
* 远程删除缓存数据
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public long bothDel(String map, String key);
public long bothDel(String hash, String key);
/**
* 远程异步删除缓存数据
*
* @param map 缓存hash
* @param key 缓存键
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public CompletableFuture<Long> bothDelAsync(String map, String key);
public CompletableFuture<Long> bothDelAsync(String hash, String key);
}

View File

@@ -0,0 +1,27 @@
/*
*
*/
package org.redkale.cache.support;
import java.lang.reflect.Method;
import org.redkale.convert.json.JsonConvert;
/**
*
* 缓存的方法对象
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
public class CacheAction {
private Method method;
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -5,9 +5,11 @@ package org.redkale.cache.support;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.function.Supplier;
import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.Component;
import org.redkale.annotation.Nullable;
@@ -35,9 +37,12 @@ import org.redkale.util.Utility;
@ResourceType(CacheManager.class)
public class CacheManagerService implements CacheManager, Service {
//缓存配置项
//是否开启缓存
protected boolean enabled = true;
//是否缓存null值
protected boolean nullable = false;
//配置
protected AnyValue config;
@@ -50,6 +55,9 @@ public class CacheManagerService implements CacheManager, Service {
//缓存hash集合, 用于定时遍历删除过期数据
protected final ConcurrentSkipListSet<String> hashNames = new ConcurrentSkipListSet<>();
//缓存无效时使用的锁
private final ConcurrentHashMap<String, CacheValue> hashLock = new ConcurrentHashMap<>();
@Resource(required = false)
protected Application application;
@@ -133,6 +141,56 @@ public class CacheManagerService implements CacheManager, Service {
return CacheValue.get(val);
}
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param expire 过期时长为null表示永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
public <T> T localGet(final String hash, final String key, final Type type, Duration expire, Supplier<T> supplier) {
Objects.requireNonNull(supplier);
Type t = loadCacheType(type);
CacheValue<T> val = localSource.hget(hash, key, t);
if (CacheValue.isValid(val)) {
return val.getValue();
}
String lockKey = lockKey(hash, key);
val = hashLock.computeIfAbsent(lockKey, k -> cacheSupplier(expire, supplier).get());
try {
if (CacheValue.isValid(val)) {
localSource.hset(hash, key, t, val);
return val.getValue();
} else {
return null;
}
} finally {
hashLock.remove(lockKey);
}
}
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param expire 过期时长为null表示永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
@Override
public <T> CompletableFuture<T> localGetAsync(String hash, String key, Type type, Duration expire, Supplier<CompletableFuture<T>> supplier) {
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* 本地缓存数据
*
@@ -377,6 +435,45 @@ public class CacheManagerService implements CacheManager, Service {
}
//-------------------------------------- 内部方法 --------------------------------------
/**
* 创建一个锁key
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return
*/
protected String lockKey(String hash, String key) {
return hash + (char) 8 + key;
}
/**
* 将原始数据函数转换成获取CacheValue数据函数
*
* @param expire 过期时长为null表示永不过期
* @param supplier 数据函数
*
* @return CacheValue函数
*/
protected <T> CacheValue<T> cacheFunc(Duration expire, T value) {
if (value == null) {
return nullable ? CacheValue.create(value, expire) : null;
}
return CacheValue.create(value, expire);
}
/**
* 将原始数据函数转换成获取CacheValue数据函数
*
* @param expire 过期时长为null表示永不过期
* @param supplier 数据函数
*
* @return CacheValue函数
*/
protected <T> Supplier<CacheValue<T>> cacheSupplier(Duration expire, Supplier<T> supplier) {
return () -> cacheFunc(expire, supplier.get());
}
/**
* 创建数据类型创建对应CacheValue泛型
*
@@ -399,4 +496,5 @@ public class CacheManagerService implements CacheManager, Service {
protected Type loadCacheType(Type type) {
return cacheValueTypes.computeIfAbsent(type, t -> TypeToken.createParameterizedType(null, CacheValue.class, type));
}
}

View File

@@ -1,7 +1,7 @@
/*
*
*/
package org.redkale.locking;
package org.redkale.lock;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.METHOD;