是否可以将咖啡因CacheLoader::loadAll与@Cacheable带有集合参数的带注释方法一起使用,例如
@Cacheable(cacheNames = "exampleCache", cacheManager="exampleCacheManager", keyGenerator = "complexKeyGenerator")
List<String> getItems(List<String> keys, String commonForEveryKey) {
return ...
}
@Component
class ComplexKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return ((List<String>)params[0]).stream()
.map(item -> new ComplexKey(item, (String) params[1]))
.collect(Collectors.toList());
}
}
@Data
@AllArgsConstructor
class ComplexKey {
String key;
String commonGuy;
}
class CustomCacheLoader implements CacheLoader<ComplexKey, String> {
@Override
public @Nullable String load(@NonNull ComplexKey key) throws Exception {
return loadAll(List.of(key)).get(key);
}
@Override
public @NonNull …Run Code Online (Sandbox Code Playgroud) 如何解决Spring Cloud LoadBalancer is currently working with the default cache. You can switch to using Caffeine cache, by adding it to the classpath.spring boot中的警告?
我正在尝试将咖啡因缓存集成到 kotlin+spring boot 应用程序中,但是,我遇到了在非协程主体中调用暂停函数的问题。我明白了,但我正在寻找一个应该更标准的解决方案。我在网上只能找到一个导致 SO 的解决方案,但我并没有真正找到解决此问题的稳定方法。
inMemoryCache.get(id) { id ->
some call to external service <--- "Suspension function can be called only within coroutine body"
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 Caffeine 缓存来存储从外部系统接收到的数据。
LoadingCache<String, String> clientCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(id -> {
System.out.println("Generating new value for " + id);
if (id.equalsIgnoreCase("1")) {
return null;
}
return new Date().toString();
});
System.out.println(clientCache.get("1"));
System.out.println(clientCache.get("1"));
System.out.println(clientCache.get("2"));
System.out.println(clientCache.get("3"));
Run Code Online (Sandbox Code Playgroud)
这导致,
Generating new value for 1
null
Generating new value for 1
null
Generating new value for 2
Wed May 20 17:11:01 IST 2020
Generating new value for 3
Wed May 20 17:11:01 IST 2020
Wed May 20 17:11:01 IST 2020
Run Code Online (Sandbox Code Playgroud)
咖啡因不会在缓存中保存空值。如何在咖啡因中存储空值?
我试图在 micronaut 中定义咖啡因缓存,并通过应用程序 yaml 设置过期时间。
文档表明
micronaut.caches.discovery-client.expire-after-write应该被定义为一个Duration对象,但不清楚如何在 YAML 中这样做。
---
micronaut:
application:
name: example-service
caches:
example-cache:
expire-after-write: 86400
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
Internal Server Error: Failed to inject value for parameter [expireAfterWrite] of method [setExpireAfterWrite] of class: io.micronaut.cache.caffeine.DefaultCacheConfiguration
Message: Error resolving property value [micronaut.caches.example-cache.expire-after-write]. Property doesn't exist
Path Taken: new $ExampleControllerDefinition$Intercepted(BeanContext beanContext,Qualifier qualifier,[Interceptor[] interceptors]) --> new CacheInterceptor([CacheManager cacheManager],CacheErrorHandler errorHandler,AsyncCacheErrorHandler asyncCacheErrorHandler,ExecutorService ioExecutor,BeanContext beanContext) --> new DefaultCacheManager([List caches],Provider dynamicCacheManager) --> new DefaultSyncCache([CacheConfiguration cacheConfiguration],ApplicationContext applicationContext,ConversionService conversionService) --> DefaultCacheConfiguration.setExpireAfterWrite([Duration expireAfterWrite])
io.micronaut.http.client.exceptions.HttpClientResponseException: Internal Server …Run Code Online (Sandbox Code Playgroud) 我有一个 Spring Cloud 网关,它将 API 剩余请求转发到一些微服务。
我想缓存特定请求的响应。为此我写了这个过滤器
@Component
@Slf4j
public class CacheResponseGatewayFilterFactory extends AbstractGatewayFilterFactory<CacheResponseGatewayFilterFactory.Config> {
private final CacheManager cacheManager;
public CacheResponseGatewayFilterFactory(CacheManager cacheManager) {
super(CacheResponseGatewayFilterFactory.Config.class);
this.cacheManager = cacheManager;
}
@Override
public GatewayFilter apply(CacheResponseGatewayFilterFactory.Config config) {
final var cache = cacheManager.getCache("MyCache");
return (exchange, chain) -> {
final var path = exchange.getRequest().getPath();
if (nonNull(cache.get(path))) {
log.info("Return cached response for request: {}", path);
final var response = cache.get(path, ServerHttpResponse.class);
final var mutatedExchange = exchange.mutate().response(response).build();
return mutatedExchange.getResponse().setComplete();
}
return chain.filter(exchange).doOnSuccess(aVoid -> {
cache.put(path, exchange.getResponse());
}); …Run Code Online (Sandbox Code Playgroud) spring spring-boot spring-cache spring-cloud-gateway caffeine-cache
我正在为 Spring Cache 使用 Caffeine Cache 库。有没有办法获取所有缓存的密钥?
我当前的应用程序处理近实时数据,流程如下:
在Cache Updater Thread(以固定时间间隔运行,与用户请求无关)中,我需要获取当前缓存中的所有键,从 Db 获取它们的最新数据,然后用于@CachePut更新缓存。
我在以下配置中使用咖啡因:
Cache<String, String> cache = Caffeine.newBuilder()
.executor(newWorkStealingPool(15))
.scheduler(createScheduler())
.expireAfterWrite(10, TimeUnit.SECONDS)
.maximumSize(MAXIMUM_CACHE_SIZE)
.removalListener(this::onRemoval)
.build();
private Scheduler createScheduler() {
return forScheduledExecutorService(newSingleThreadScheduledExecutor());
}
Run Code Online (Sandbox Code Playgroud)
我是否正确地假设该onRemoval方法将在 ForkJoinPool 上执行newWorkStealingPool(15),并且只会调用调度程序来查找需要驱逐的过期条目?
这意味着它会像这样:
newWorkStealingPool(15)对缓存构建器中的定义中的每个被逐出的条目执行 onRemoval 吗?我没有找到解释此行为的文档,所以我在这里询问
总氮
我想将我的Caffeine缓存配置为在加载程序无法刷新缓存时返回过时的结果。以下 Kotlin 代码演示了这种情况:
@Test
fun `completeble future`() = runBlocking {
val cache = Caffeine.newBuilder()
.refreshAfterWrite(Duration.ofSeconds(1))
.expireAfterWrite(Duration.ofSeconds(1))
.buildAsync<String, String> { key: String, executor ->
GlobalScope.future(executor.asCoroutineDispatcher()) {
throw Exception("== Error ==")
}
}
cache.put("id", CompletableFuture.completedFuture("value"))
delay(2000)
assertEquals("value", cache.get("id").await())
}
Run Code Online (Sandbox Code Playgroud)
我希望这个测试能够通过,但我收到以下错误:
WARNING: Exception thrown during asynchronous load
java.lang.Exception: == Error ==
at fsra.manager.TranslationManagerImplTest$completeble future$1$cache$1$1.invokeSuspend(TranslationManagerImplTest.kt:93)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
java.lang.Exception: == Error ==
at fsra.manager.TranslationManagerImplTest$completeble future$1$cache$1$1.invokeSuspend(TranslationManagerImplTest.kt:93)
at |b|b|b(Coroutine boundary.|b(|b)
at …Run Code Online (Sandbox Code Playgroud) java ×5
spring-boot ×5
caffeine ×4
caching ×3
spring-cache ×3
kotlin ×2
spring ×2
java-8 ×1
micronaut ×1
yaml ×1