LockedAction

This commit is contained in:
redkale
2024-06-08 16:32:52 +08:00
parent bbf72bb27b
commit 6bcb1de304
7 changed files with 88 additions and 16 deletions

View File

@@ -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,15 +867,27 @@ 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)) {
if (expire != null) {
if (logable) {
logger.log(logLevel, "Cached set id(" + id + ") value to localSource from remoteSource");
}
setCache(localSource, id, expire, cacheType, cacheVal); setCache(localSource, id, expire, cacheType, cacheVal);
} }
if (logable) {
logger.log(logLevel, "Cached got id(" + id + ") value from remoteSource");
}
}
return cacheVal; return cacheVal;
} else { } else {
return null; return null;
@@ -869,16 +905,28 @@ 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)) {
if (expire != null) {
if (logable) {
logger.log(logLevel, "Cached set id(" + id + ") value to localSource from remoteSource");
}
setCache(localSource, id, expire, cacheType, v); setCache(localSource, id, expire, cacheType, v);
} }
if (logable) {
logger.log(logLevel, "Cached got id(" + id + ") value from remoteSource");
}
}
return v; return v;
}); });
} else { } else {

View File

@@ -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

View 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 {}

View File

@@ -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);

View File

@@ -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<>();

View File

@@ -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();

View File

@@ -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();