LockedAction
This commit is contained in:
@@ -10,6 +10,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.annotation.AutoLoad;
|
||||
import org.redkale.annotation.Component;
|
||||
import org.redkale.annotation.Nullable;
|
||||
@@ -43,6 +45,10 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
|
||||
public static final String CACHE_CHANNEL_TOPIC = "cache-update-channel";
|
||||
|
||||
protected final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
protected Level logLevel = Level.FINER;
|
||||
|
||||
// 是否开启缓存
|
||||
protected boolean enabled = true;
|
||||
|
||||
@@ -681,12 +687,16 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
Duration expire,
|
||||
ThrowSupplier<T> supplier) {
|
||||
checkEnable();
|
||||
boolean logable = logger.isLoggable(logLevel);
|
||||
Objects.requireNonNull(expire);
|
||||
Objects.requireNonNull(supplier);
|
||||
final Type cacheType = loadCacheType(type);
|
||||
final String id = idFor(schema, key);
|
||||
CachedValue<T> cacheVal = getter.get(id, expire, cacheType);
|
||||
if (CachedValue.isValid(cacheVal)) {
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached got id(" + id + ") value from eitherSource");
|
||||
}
|
||||
return cacheVal.getVal();
|
||||
}
|
||||
Function<String, CachedValue> func = k -> {
|
||||
@@ -739,12 +749,16 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
Duration expire,
|
||||
ThrowSupplier<CompletableFuture<T>> supplier) {
|
||||
checkEnable();
|
||||
boolean logable = logger.isLoggable(logLevel);
|
||||
Objects.requireNonNull(supplier);
|
||||
final Type cacheType = loadCacheType(type);
|
||||
final String id = idFor(schema, key);
|
||||
CompletableFuture<CachedValue<T>> sourceFuture = getter.get(id, expire, cacheType);
|
||||
return sourceFuture.thenCompose(val -> {
|
||||
if (CachedValue.isValid(val)) {
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached got id(" + id + ") value from eitherSource");
|
||||
}
|
||||
return CompletableFuture.completedFuture(val.getVal());
|
||||
}
|
||||
final CachedAsyncLock lock = asyncLockMap.computeIfAbsent(id, k -> new CachedAsyncLock(asyncLockMap, k));
|
||||
@@ -792,8 +806,13 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
protected <T> void setCache(
|
||||
CacheSource source, String id, Duration expire, Type cacheType, CachedValue<T> cacheVal) {
|
||||
checkEnable();
|
||||
boolean logable = logger.isLoggable(logLevel);
|
||||
Objects.requireNonNull(expire);
|
||||
long millis = expire.toMillis();
|
||||
if (logable) {
|
||||
String s = source == localSource ? "localSource" : "remoteSource";
|
||||
logger.log(logLevel, "Cached set id(" + id + ") value to " + s + " expire " + millis + " ms");
|
||||
}
|
||||
if (millis > 0) {
|
||||
source.psetex(id, millis, cacheType, cacheVal);
|
||||
} else {
|
||||
@@ -804,8 +823,13 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
protected <T> CompletableFuture<Void> setCacheAsync(
|
||||
CacheSource source, String id, Duration expire, Type cacheType, CachedValue<T> cacheVal) {
|
||||
checkEnable();
|
||||
boolean logable = logger.isLoggable(logLevel);
|
||||
Objects.requireNonNull(expire);
|
||||
long millis = expire.toMillis();
|
||||
if (logable) {
|
||||
String s = source == localSource ? "localSource" : "remoteSource";
|
||||
logger.log(logLevel, "Cached set id(" + id + ") value to " + s + " expire " + millis + " ms");
|
||||
}
|
||||
if (millis > 0) {
|
||||
return source.psetexAsync(id, millis, cacheType, cacheVal);
|
||||
} else {
|
||||
@@ -843,14 +867,26 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
|
||||
protected <T> CachedValue<T> bothGetCache(final String id, final Duration expire, final Type cacheType) {
|
||||
checkEnable();
|
||||
boolean logable = logger.isLoggable(logLevel);
|
||||
CachedValue<T> cacheVal = localSource.get(id, cacheType);
|
||||
if (CachedValue.isValid(cacheVal)) {
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached got id(" + id + ") value from localSource");
|
||||
}
|
||||
return cacheVal;
|
||||
}
|
||||
if (remoteSource != null) {
|
||||
cacheVal = remoteSource.get(id, cacheType);
|
||||
if (CachedValue.isValid(cacheVal) && expire != null) {
|
||||
setCache(localSource, id, expire, cacheType, cacheVal);
|
||||
if (CachedValue.isValid(cacheVal)) {
|
||||
if (expire != null) {
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached set id(" + id + ") value to localSource from remoteSource");
|
||||
}
|
||||
setCache(localSource, id, expire, cacheType, cacheVal);
|
||||
}
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached got id(" + id + ") value from remoteSource");
|
||||
}
|
||||
}
|
||||
return cacheVal;
|
||||
} else {
|
||||
@@ -869,15 +905,27 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
*/
|
||||
protected <T> CompletableFuture<CachedValue<T>> bothGetCacheAsync(String id, Duration expire, Type cacheType) {
|
||||
checkEnable();
|
||||
boolean logable = logger.isLoggable(logLevel);
|
||||
CachedValue<T> val = localSource.get(id, cacheType); // 内存操作,无需异步
|
||||
if (CachedValue.isValid(val)) {
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached got id(" + id + ") value from localSource");
|
||||
}
|
||||
return CompletableFuture.completedFuture(val);
|
||||
}
|
||||
if (remoteSource != null) {
|
||||
CompletableFuture<CachedValue<T>> future = remoteSource.getAsync(id, cacheType);
|
||||
return future.thenApply(v -> {
|
||||
if (CachedValue.isValid(v) && expire != null) {
|
||||
setCache(localSource, id, expire, cacheType, v);
|
||||
if (CachedValue.isValid(v)) {
|
||||
if (expire != null) {
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached set id(" + id + ") value to localSource from remoteSource");
|
||||
}
|
||||
setCache(localSource, id, expire, cacheType, v);
|
||||
}
|
||||
if (logable) {
|
||||
logger.log(logLevel, "Cached got id(" + id + ") value from remoteSource");
|
||||
}
|
||||
}
|
||||
return v;
|
||||
});
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
*/
|
||||
package org.redkale.locked.spi;
|
||||
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import java.lang.annotation.Retention;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import java.lang.annotation.Target;
|
||||
import org.redkale.service.LoadMode;
|
||||
|
||||
/**
|
||||
* {@link org.redkale.lock.Locked}注解的动态扩展版,会多一个字段信息 用于识别方法是否已经动态处理过
|
||||
* {@link org.redkale.locked.Locked}注解的动态扩展版,会多一个字段信息 用于识别方法是否已经动态处理过
|
||||
*
|
||||
* @author zhangjx
|
||||
* @since 2.8.0
|
||||
|
||||
18
src/main/java/org/redkale/locked/spi/LockedAction.java
Normal file
18
src/main/java/org/redkale/locked/spi/LockedAction.java
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.locked.spi;
|
||||
|
||||
import org.redkale.annotation.ClassDepends;
|
||||
|
||||
/**
|
||||
* 锁的方法对象
|
||||
*
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
* @since 2.8.0
|
||||
*/
|
||||
@ClassDepends
|
||||
public class LockedAction {}
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
package org.redkale.locked.spi;
|
||||
|
||||
import static org.redkale.asm.Opcodes.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -16,6 +14,7 @@ import org.redkale.asm.Asms;
|
||||
import org.redkale.asm.ClassWriter;
|
||||
import org.redkale.asm.Label;
|
||||
import org.redkale.asm.MethodVisitor;
|
||||
import static org.redkale.asm.Opcodes.*;
|
||||
import org.redkale.asm.Type;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.locked.Locked;
|
||||
@@ -64,8 +63,9 @@ public class LockedAsmMethodBoost extends AsmMethodBoost {
|
||||
"@" + Locked.class.getSimpleName() + " must on protected or public method, but on " + method);
|
||||
}
|
||||
|
||||
final String rsMethodName = method.getName() + "_afterLock";
|
||||
final String dynFieldName = fieldPrefix + "_" + method.getName() + "LockAction" + fieldIndex.incrementAndGet();
|
||||
final String rsMethodName = method.getName() + "_afterLocked";
|
||||
final String dynFieldName = fieldPrefix + "_" + method.getName() + LockedAction.class.getSimpleName()
|
||||
+ fieldIndex.incrementAndGet();
|
||||
{ // 定义一个新方法调用 this.rsMethodName
|
||||
final AsmMethodBean methodBean = getMethodBean(method);
|
||||
final String lockDynDesc = Type.getDescriptor(DynForLocked.class);
|
||||
|
||||
@@ -10,15 +10,17 @@ import java.util.ServiceLoader;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import org.redkale.boot.Application;
|
||||
import org.redkale.boot.ModuleEngine;
|
||||
import org.redkale.locked.LockedManager;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.InstanceProvider;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.locked.LockedManager;
|
||||
|
||||
/** @author zhangjx */
|
||||
public class LockedModuleEngine extends ModuleEngine {
|
||||
|
||||
protected static final String CONFIG_NAME = "locked";
|
||||
|
||||
// 全局锁管理器
|
||||
private LockedManager lockManager;
|
||||
|
||||
@@ -39,7 +41,7 @@ public class LockedModuleEngine extends ModuleEngine {
|
||||
*/
|
||||
@Override
|
||||
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
|
||||
if ("".equals(path) && "lock".equals(key)) {
|
||||
if ("".equals(path) && CONFIG_NAME.equals(key)) {
|
||||
return AnyValue.MergeEnum.REPLACE;
|
||||
}
|
||||
return null;
|
||||
@@ -60,7 +62,7 @@ public class LockedModuleEngine extends ModuleEngine {
|
||||
@Override
|
||||
public void onAppPostInit() {
|
||||
// 设置锁管理器
|
||||
this.config = application.getAppConfig().getAnyValue("lock");
|
||||
this.config = application.getAppConfig().getAnyValue(CONFIG_NAME);
|
||||
this.lockManager = createManager(this.config);
|
||||
if (!application.isCompileMode()) {
|
||||
this.resourceFactory.inject(this.lockManager);
|
||||
@@ -80,7 +82,8 @@ public class LockedModuleEngine extends ModuleEngine {
|
||||
}
|
||||
|
||||
private LockedManager createManager(AnyValue conf) {
|
||||
Iterator<LockedManagerProvider> it = ServiceLoader.load(LockedManagerProvider.class, application.getClassLoader())
|
||||
Iterator<LockedManagerProvider> it = ServiceLoader.load(
|
||||
LockedManagerProvider.class, application.getClassLoader())
|
||||
.iterator();
|
||||
RedkaleClassLoader.putServiceLoader(LockedManagerProvider.class);
|
||||
List<LockedManagerProvider> providers = new ArrayList<>();
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.concurrent.CountDownLatch;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.redkale.boot.LoggingBaseHandler;
|
||||
import org.redkale.cached.CachedManager;
|
||||
import org.redkale.cached.spi.CachedAsmMethodBoost;
|
||||
import org.redkale.cached.spi.CachedManagerService;
|
||||
@@ -33,6 +34,7 @@ public class CachedInstanceTest {
|
||||
private static CachedManagerService manager2;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
LoggingBaseHandler.initDebugLogConfig();
|
||||
CachedInstanceTest test = new CachedInstanceTest();
|
||||
init();
|
||||
test.run1();
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.time.Duration;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.redkale.boot.LoggingBaseHandler;
|
||||
import org.redkale.cached.spi.CachedManagerService;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.source.CacheMemorySource;
|
||||
@@ -18,6 +19,7 @@ public class CachedManagerTest {
|
||||
private static CachedManagerService manager;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
LoggingBaseHandler.initDebugLogConfig();
|
||||
CachedManagerTest test = new CachedManagerTest();
|
||||
init();
|
||||
test.run1();
|
||||
|
||||
Reference in New Issue
Block a user