diff --git a/src/main/java/org/redkale/cache/CacheManager.java b/src/main/java/org/redkale/cache/CacheManager.java index 7122b7da4..0adb6e250 100644 --- a/src/main/java/org/redkale/cache/CacheManager.java +++ b/src/main/java/org/redkale/cache/CacheManager.java @@ -6,7 +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; +import org.redkale.util.ThrowSupplier; /** * 缓存管理器 @@ -58,7 +58,7 @@ public interface CacheManager { * * @return 数据值 */ - public T localGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, Supplier supplier); + public T localGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier supplier); /** * 本地异步获取缓存数据, 过期返回null @@ -73,7 +73,7 @@ public interface CacheManager { * * @return 数据值 */ - public CompletableFuture localGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, Supplier> supplier); + public CompletableFuture localGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier> supplier); /** * 本地缓存数据 @@ -172,7 +172,7 @@ public interface CacheManager { * @return 数据值 */ public T remoteGetSet(final String hash, final String key, final Type type, boolean nullable, - Duration expire, Supplier supplier); + Duration expire, ThrowSupplier supplier); /** * 远程异步获取缓存数据, 过期返回null @@ -188,7 +188,7 @@ public interface CacheManager { * @return 数据值 */ public CompletableFuture remoteGetSetAsync(String hash, String key, Type type, boolean nullable, - Duration expire, Supplier> supplier); + Duration expire, ThrowSupplier> supplier); /** * 远程缓存数据 @@ -326,7 +326,7 @@ public interface CacheManager { * @return 数据值 */ public T bothGetSet(String hash, String key, Type type, boolean nullable, - Duration localExpire, Duration remoteExpire, Supplier supplier); + Duration localExpire, Duration remoteExpire, ThrowSupplier supplier); /** * 本地或远程异步获取缓存数据, 过期返回null @@ -343,7 +343,7 @@ public interface CacheManager { * @return 数据值 */ public CompletableFuture bothGetSetAsync(String hash, String key, Type type, boolean nullable, - Duration localExpire, Duration remoteExpire, Supplier> supplier); + Duration localExpire, Duration remoteExpire, ThrowSupplier> supplier); /** * 本地和远程缓存数据 diff --git a/src/main/java/org/redkale/cache/spi/CacheAction.java b/src/main/java/org/redkale/cache/spi/CacheAction.java index df482c44c..1d4cc6a91 100644 --- a/src/main/java/org/redkale/cache/spi/CacheAction.java +++ b/src/main/java/org/redkale/cache/spi/CacheAction.java @@ -8,7 +8,6 @@ import java.lang.reflect.Type; import java.time.Duration; import java.util.Objects; import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; import org.redkale.annotation.Nullable; import org.redkale.annotation.Resource; import org.redkale.cache.CacheManager; @@ -16,6 +15,7 @@ import org.redkale.convert.json.JsonConvert; import org.redkale.net.sncp.Sncp; import org.redkale.util.Environment; import org.redkale.util.MultiHashKey; +import org.redkale.util.ThrowSupplier; import org.redkale.util.TypeToken; /** @@ -100,9 +100,9 @@ public class CacheAction { this.remoteExpire = createDuration(cached.getRemoteExpire()); } - public T get(Supplier supplier, Object... args) { + public T get(ThrowSupplier supplier, Object... args) { if (async) { - Supplier supplier0 = supplier; + ThrowSupplier supplier0 = supplier; return (T) manager.bothGetSetAsync(hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier0); } else { return manager.bothGetSet(hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier); diff --git a/src/main/java/org/redkale/cache/spi/CacheManagerService.java b/src/main/java/org/redkale/cache/spi/CacheManagerService.java index 93c06fef2..b538bae5a 100644 --- a/src/main/java/org/redkale/cache/spi/CacheManagerService.java +++ b/src/main/java/org/redkale/cache/spi/CacheManagerService.java @@ -14,7 +14,6 @@ import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; -import java.util.function.Supplier; import org.redkale.annotation.AutoLoad; import org.redkale.annotation.Component; import org.redkale.annotation.Nullable; @@ -28,6 +27,7 @@ import org.redkale.source.CacheMemorySource; import org.redkale.source.CacheSource; import org.redkale.util.AnyValue; import org.redkale.util.RedkaleException; +import org.redkale.util.ThrowSupplier; import org.redkale.util.TypeToken; import org.redkale.util.Utility; @@ -157,7 +157,7 @@ public class CacheManagerService implements CacheManager, Service { * @return 数据值 */ @Override - public T localGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, Supplier supplier) { + public T localGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier supplier) { return getSet(localSource::hget, localSource::hset, hash, key, type, nullable, expire, supplier); } @@ -175,7 +175,7 @@ public class CacheManagerService implements CacheManager, Service { * @return 数据值 */ @Override - public CompletableFuture localGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, Supplier> supplier) { + public CompletableFuture localGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier> supplier) { return getSetAsync(localSource::hgetAsync, localSource::hsetAsync, hash, key, type, nullable, expire, supplier); } @@ -263,7 +263,7 @@ public class CacheManagerService implements CacheManager, Service { * @return 数据值 */ @Override - public T remoteGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, Supplier supplier) { + public T remoteGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier supplier) { return getSet(remoteSource::hget, remoteSource::hset, hash, key, type, nullable, expire, supplier); } @@ -281,7 +281,7 @@ public class CacheManagerService implements CacheManager, Service { * @return 数据值 */ @Override - public CompletableFuture remoteGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, Supplier> supplier) { + public CompletableFuture remoteGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier> supplier) { return getSetAsync(remoteSource::hgetAsync, remoteSource::hsetAsync, hash, key, type, nullable, expire, supplier); } @@ -399,9 +399,15 @@ public class CacheManagerService implements CacheManager, Service { */ @Override public T bothGetSet(final String hash, final String key, final Type type, boolean nullable, - Duration localExpire, Duration remoteExpire, Supplier supplier) { + Duration localExpire, Duration remoteExpire, ThrowSupplier supplier) { if (!enabled) { - return supplier.get(); + try { + return supplier.get(); + } catch (RuntimeException e) { + throw e; + } catch (Throwable t) { + throw new RedkaleException(t); + } } if (localExpire == null) { //只有远程缓存 Objects.requireNonNull(remoteExpire); @@ -434,9 +440,13 @@ public class CacheManagerService implements CacheManager, Service { */ @Override public CompletableFuture bothGetSetAsync(String hash, String key, Type type, boolean nullable, - Duration localExpire, Duration remoteExpire, Supplier> supplier) { + Duration localExpire, Duration remoteExpire, ThrowSupplier> supplier) { if (!enabled) { - return supplier.get(); + try { + return supplier.get(); + } catch (Throwable t) { + return CompletableFuture.failedFuture(t); + } } if (localExpire == null) { //只有远程缓存 Objects.requireNonNull(remoteExpire); @@ -560,7 +570,7 @@ public class CacheManagerService implements CacheManager, Service { * @return 数据值 */ protected T getSet(GetterFunc> getter, SetterSyncFunc setter, - String hash, String key, Type type, boolean nullable, Duration expire, Supplier supplier) { + String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier supplier) { checkEnable(); Objects.requireNonNull(expire); Objects.requireNonNull(supplier); @@ -574,7 +584,14 @@ public class CacheManagerService implements CacheManager, Service { if (CacheValue.isValid(oldCacheVal)) { return oldCacheVal; } - CacheValue newCacheVal = toCacheSupplier(nullable, expire, supplier).get(); + CacheValue newCacheVal; + try { + newCacheVal = toCacheSupplier(nullable, expire, supplier).get(); + } catch (RuntimeException e) { + throw e; + } catch (Throwable t) { + throw new RedkaleException(t); + } if (CacheValue.isValid(newCacheVal)) { setter.set(hash, key, cacheType, newCacheVal); } @@ -605,7 +622,7 @@ public class CacheManagerService implements CacheManager, Service { * @return 数据值 */ protected CompletableFuture getSetAsync(GetterFunc>> getter, SetterAsyncFunc setter, - String hash, String key, Type type, boolean nullable, Duration expire, Supplier> supplier) { + String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier> supplier) { checkEnable(); Objects.requireNonNull(supplier); final Type cacheType = loadCacheType(type); @@ -722,7 +739,7 @@ public class CacheManagerService implements CacheManager, Service { * * @return CacheValue函数 */ - protected Supplier> toCacheSupplier(boolean nullable, Duration expire, Supplier supplier) { + protected ThrowSupplier> toCacheSupplier(boolean nullable, Duration expire, ThrowSupplier supplier) { return () -> toCacheValue(nullable, expire, supplier.get()); } diff --git a/src/main/java/org/redkale/util/ThrowSupplier.java b/src/main/java/org/redkale/util/ThrowSupplier.java new file mode 100644 index 000000000..e22914926 --- /dev/null +++ b/src/main/java/org/redkale/util/ThrowSupplier.java @@ -0,0 +1,26 @@ +/* + * + */ +package org.redkale.util; + +/** + * 抛异常版的Supplier + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * + * @since 2.8.0 + */ +@FunctionalInterface +public interface ThrowSupplier { + + /** + * Gets a result. + * + * @return a result + */ + T get() throws Throwable; + +} diff --git a/src/test/java/org/redkale/test/cache/BaseService.java b/src/test/java/org/redkale/test/cache/BaseService.java deleted file mode 100644 index 6cde83d23..000000000 --- a/src/test/java/org/redkale/test/cache/BaseService.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - */ -package org.redkale.test.cache; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * - * @author zhangjx - */ -public class BaseService { - - private void run1() { - } - - protected void run2() { - } - - public void run3() { - } - - public Map toMap(List a, Set set){ - return null; - } -} diff --git a/src/test/java/org/redkale/test/cache/CacheInstance.java b/src/test/java/org/redkale/test/cache/CacheInstance.java new file mode 100644 index 000000000..a8f2f3665 --- /dev/null +++ b/src/test/java/org/redkale/test/cache/CacheInstance.java @@ -0,0 +1,100 @@ +/* + * + */ +package org.redkale.test.cache; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import org.redkale.cache.Cached; +import org.redkale.service.Service; +import org.redkale.source.Range; +import org.redkale.util.RedkaleException; + +/** + * + * @author zhangjx + */ +public class CacheInstance implements Service { + + @Cached(key = "name", localExpire = "30") + public String getName() { + return "haha"; + } + + @Cached(key = "name", localExpire = "30", remoteExpire = "60") + public String getName2() throws RedkaleException { + return "haha"; + } + + @Cached(key = "name", localExpire = "30") + public CompletableFuture getNameAsync() { + return CompletableFuture.completedFuture("nameAsync"); + } + + @Cached(key = "name", localExpire = "30", remoteExpire = "60") + public CompletableFuture getName2Async() throws IOException, InstantiationException { + return CompletableFuture.completedFuture("name2Async"); + } + + @Cached(key = "info_#{id}_file#{files.one}", localExpire = "30", remoteExpire = "60") + public File getInfo(ParamBean bean, int id, List idList, Map files) { + return new File("aa.txt"); + } + + @Cached(key = "info_#{id}_file#{files.one}", localExpire = "30", remoteExpire = "60") + public CompletableFuture getInfoAsync(ParamBean bean, int id, List idList, Map files) { + return CompletableFuture.completedFuture(new File("aa.txt")); + } + + @Cached(key = "info_#{id}_file#{files.one}", localExpire = "30", remoteExpire = "60") + public CompletableFuture> getInfo2Async(ParamBean bean, int id, List idList, Map files) throws IOException, InstantiationException { + return CompletableFuture.completedFuture(null); + } + + public static class ParamBean { + + private String name; + + private int day; + + private Integer status; + + private Range.IntRange range; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getDay() { + return day; + } + + public void setDay(int day) { + this.day = day; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Range.IntRange getRange() { + return range; + } + + public void setRange(Range.IntRange range) { + this.range = range; + } + + } +} diff --git a/src/test/java/org/redkale/test/cache/CacheInstanceTest.java b/src/test/java/org/redkale/test/cache/CacheInstanceTest.java new file mode 100644 index 000000000..6d8e7c17e --- /dev/null +++ b/src/test/java/org/redkale/test/cache/CacheInstanceTest.java @@ -0,0 +1,66 @@ +/* + * + */ +package org.redkale.test.cache; + +import java.net.InetSocketAddress; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.redkale.cache.CacheManager; +import org.redkale.cache.spi.CacheAsmMethodBoost; +import org.redkale.cache.spi.CacheManagerService; +import org.redkale.inject.ResourceFactory; +import org.redkale.net.AsyncGroup; +import org.redkale.net.client.ClientAddress; +import org.redkale.net.sncp.Sncp; +import org.redkale.net.sncp.SncpClient; +import org.redkale.net.sncp.SncpRpcGroups; +import org.redkale.source.CacheMemorySource; +import org.redkale.util.Environment; +import org.redkale.util.Utility; + +/** + * + * @author zhangjx + */ +public class CacheInstanceTest { + + private static ResourceFactory resourceFactory; + + private static CacheManagerService manager; + + public static void main(String[] args) throws Throwable { + CacheInstanceTest test = new CacheInstanceTest(); + init(); + test.run1(); + test.run2(); + } + + @BeforeAll + public static void init() throws Exception { + resourceFactory = ResourceFactory.create(); + resourceFactory.register(new Environment()); + CacheMemorySource remoteSource = new CacheMemorySource("cache-remote"); + remoteSource.init(null); + manager = CacheManagerService.create(remoteSource); + manager.init(null); + resourceFactory.register("", CacheManager.class, manager); + } + + @Test + public void run1() throws Exception { + Class serviceClass = CacheInstance.class; + CacheAsmMethodBoost boost = new CacheAsmMethodBoost(serviceClass); + SncpRpcGroups grous = new SncpRpcGroups(); + AsyncGroup iGroup = AsyncGroup.create("", Utility.newScheduledExecutor(1), 0, 0); + SncpClient client = new SncpClient("", iGroup, 0, new InetSocketAddress("127.0.0.1", 8080), new ClientAddress(), "TCP", 1, 16); + CacheInstance instance = Sncp.createLocalService(null, "", serviceClass, boost, resourceFactory, + grous, client, null, null, null); + System.out.println(instance.getName()); + } + + @Test + public void run2() throws Exception { + + } +} diff --git a/src/test/java/org/redkale/test/cache/CacheManagerTest.java b/src/test/java/org/redkale/test/cache/CacheManagerTest.java index 298932a82..b69a3add5 100644 --- a/src/test/java/org/redkale/test/cache/CacheManagerTest.java +++ b/src/test/java/org/redkale/test/cache/CacheManagerTest.java @@ -22,7 +22,7 @@ public class CacheManagerTest { public static void main(String[] args) throws Throwable { CacheManagerTest test = new CacheManagerTest(); - test.init(); + init(); test.run1(); test.run2(); } diff --git a/src/test/java/org/redkale/test/cache/SimpleService.java b/src/test/java/org/redkale/test/cache/SimpleService.java deleted file mode 100644 index 7e672cb98..000000000 --- a/src/test/java/org/redkale/test/cache/SimpleService.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - - */ - -package org.redkale.test.cache; - -/** - * - * @author zhangjx - */ -public class SimpleService extends BaseService { - -} diff --git a/src/test/java/org/redkale/test/cache/TwoService.java b/src/test/java/org/redkale/test/cache/TwoService.java deleted file mode 100644 index 5b42f8cd5..000000000 --- a/src/test/java/org/redkale/test/cache/TwoService.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - */ -package org.redkale.test.cache; - -import java.lang.reflect.Method; -import org.redkale.asm.AsmMethodBoost; -import org.redkale.asm.Type; - -/** - * - * @author zhangjx - */ -public class TwoService extends BaseService { - - @Override - protected void run2() { - } - - @Override - public void run3() { - } - - public static void main(String[] args) throws Throwable { - System.out.println("-------------------------------"); - for (Method m : TwoService.class.getDeclaredMethods()) { - System.out.println(m); - } - System.out.println("-------------------------------"); - for (Method m : SimpleService.class.getDeclaredMethods()) { - System.out.println(m); - } - System.out.println("-------------------------------"); - for (Method m : BaseService.class.getDeclaredMethods()) { - System.out.println(m); - if(m.getName().equals("toMap")) { - System.out.println("张颠三倒四: " + Type.getType(m).getInternalName()); - System.out.println("张颠三倒四: " + Type.getType(m).getDescriptor()); - System.out.println("张颠三倒四: " + Type.getType(m).getClassName()); - } - } - System.out.println("-------------------------------"); - System.out.println(AsmMethodBoost.getMethodBeans(BaseService.class)); - } -} diff --git a/src/test/java/org/redkale/test/cache/_DynLocalCacheInstance.java b/src/test/java/org/redkale/test/cache/_DynLocalCacheInstance.java new file mode 100644 index 000000000..6c8ab70e7 --- /dev/null +++ b/src/test/java/org/redkale/test/cache/_DynLocalCacheInstance.java @@ -0,0 +1,124 @@ +/* + * + */ +package org.redkale.test.cache; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.redkale.annotation.Resource; +import org.redkale.annotation.ResourceType; +import org.redkale.cache.spi.CacheAction; +import org.redkale.cache.spi.DynForCache; +import org.redkale.net.sncp.Sncp.SncpDyn; +import org.redkale.util.AnyValue; +import org.redkale.util.RedkaleException; +import org.redkale.util.ThrowSupplier; + +@Resource( + name = "" +) +@SncpDyn( + remote = false, + type = CacheInstance.class +) +@ResourceType(CacheInstance.class) +public class _DynLocalCacheInstance extends CacheInstance { + + private AnyValue _redkale_conf; + + private String _redkale_mq; + + private CacheAction _redkale_getNameCacheAction1; + + private CacheAction _redkale_getInfoCacheAction2; + + private CacheAction _redkale_getNameAsyncCacheAction3; + + private CacheAction _redkale_getInfo2AsyncCacheAction4; + + private CacheAction _redkale_getName2AsyncCacheAction5; + + private CacheAction _redkale_getInfoAsyncCacheAction6; + + private CacheAction _redkale_getName2CacheAction7; + + public _DynLocalCacheInstance() { + } + + @DynForCache(dynField = "_redkale_getNameCacheAction1", hash = "", key = "name", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "-1", localExpire = "30" + ) + public String getName() { + ThrowSupplier supplier = () -> this.getName_afterCache(); + return _redkale_getNameCacheAction1.get(supplier); + } + + private String getName_afterCache() { + return super.getName(); + } + + @DynForCache(dynField = "_redkale_getInfoCacheAction2", hash = "", key = "info_#{id}_file#{files.one}", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "60", localExpire = "30") + public File getInfo(CacheInstance.ParamBean bean, int id, List idList, Map files) { + ThrowSupplier supplier = () -> this.getInfo_afterCache(bean, id, idList, files); + return _redkale_getInfoCacheAction2.get(supplier); + } + + private File getInfo_afterCache(CacheInstance.ParamBean bean, int id, List idList, Map files) { + return super.getInfo(bean, id, idList, files); + } + + @DynForCache(dynField = "_redkale_getNameAsyncCacheAction3", hash = "", key = "name", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "-1", localExpire = "30") + public CompletableFuture getNameAsync() { + ThrowSupplier> supplier = () -> this.getNameAsync_afterCache(); + return _redkale_getNameAsyncCacheAction3.get(supplier); + } + + private CompletableFuture getNameAsync_afterCache() { + return super.getNameAsync(); + } + + @DynForCache(dynField = "_redkale_getInfo2AsyncCacheAction4", hash = "", key = "info_#{id}_file#{files.one}", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "60", localExpire = "30") + public CompletableFuture> getInfo2Async(CacheInstance.ParamBean bean, int id, + List idList, Map files) throws IOException, InstantiationException { + ThrowSupplier>> supplier = () -> this.getInfo2Async_afterCache(bean, id, idList, files); + return _redkale_getInfo2AsyncCacheAction4.get(supplier, bean, id, idList, files); + } + + private CompletableFuture> getInfo2Async_afterCache(CacheInstance.ParamBean bean, int id, + List idList, Map files) throws IOException, InstantiationException { + return super.getInfo2Async(bean, id, idList, files); + } + + @DynForCache(dynField = "_redkale_getName2AsyncCacheAction5", hash = "", key = "name", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "60", localExpire = "30") + public CompletableFuture getName2Async() throws IOException, InstantiationException { + ThrowSupplier> supplier = () -> this.getName2Async_afterCache(); + return _redkale_getName2AsyncCacheAction5.get(supplier); + } + + private CompletableFuture getName2Async_afterCache() throws IOException, InstantiationException { + return super.getName2Async(); + } + + @DynForCache(dynField = "_redkale_getInfoAsyncCacheAction6", hash = "", key = "info_#{id}_file#{files.one}", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "60", localExpire = "30") + public CompletableFuture getInfoAsync(CacheInstance.ParamBean bean, int id, List idList, Map files) { + ThrowSupplier> supplier = () -> this.getInfoAsync_afterCache(bean, id, idList, files); + return _redkale_getInfoAsyncCacheAction6.get(supplier, bean, id, idList, files); + } + + private CompletableFuture getInfoAsync_afterCache(CacheInstance.ParamBean bean, int id, List idList, Map files) { + return super.getInfoAsync(bean, id, idList, files); + } + + @DynForCache(dynField = "_redkale_getName2CacheAction7", hash = "", key = "name", nullable = false, timeUnit = TimeUnit.SECONDS, remoteExpire = "60", localExpire = "30") + public String getName2() throws RedkaleException { + ThrowSupplier supplier = () -> this.getName2_afterCache(); + return _redkale_getName2CacheAction7.get(supplier); + } + + private String getName2_afterCache() throws RedkaleException { + return super.getName2(); + } +}