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