如果使用咖啡因和春季使用咖啡因,请使用旧/陈旧的缓存值

发布于 2025-02-07 18:12:46 字数 2250 浏览 0 评论 0 原文

如果缓存刷新失败,我需要使用旧/陈旧的高速缓存值。 我已经浏览了Internet上的许多示例,并决定尝试使用咖啡因缓存来实现此要求(更具体地使用RefReshafterWrite功能)。我能够使用咖啡因来缓存数据,但是当缓存刷新(REST API失败)失败时,无法获得旧/陈旧的值。 我已经使用了SimpleCacheManager(org.springframework.cache.support.simplecachemanager)和caffeinecache。

**simpleCacheManager bean code** :

    <bean id="simpleCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches" ref="caffeineCaches" />
    </bean>

**caffeine cache** :

    @Bean
    public Collection<? extends org.springframework.cache.Cache> caffeineCaches(){
        Collection<CaffeineCache> caffeineCaches = new ArrayList<>();
        caffeineCaches.add(new CaffeineCache("pbdBankRegistry",
                Caffeine.newBuilder()
                        .refreshAfterWrite(2, TimeUnit.MINUTES)
                        .initialCapacity(1)
                        .maximumSize(2)
                        .recordStats()
                        .build(new CustomCacheLoader()),false));
        return caffeineCaches;
    }


  **CacheLoader Code :**

    public class CustomCacheLoader implements CacheLoader<Object, Object> {
    @Nullable
    @Override
    public Object load(Object o) throws Exception {
        return null;
    }

    @Override
    public Map loadAll(Set keys) throws Exception {
        return CacheLoader.super.loadAll(keys);
    }

    @Override
    public CompletableFuture asyncLoad(Object key, Executor executor) throws Exception {
        return CacheLoader.super.asyncLoad(key, executor);
    }

    @Override
    public CompletableFuture<? extends Map> asyncLoadAll(Set keys, Executor executor) throws Exception {
        return CacheLoader.super.asyncLoadAll(keys, executor);
    }

    @Nullable
    @Override
    public Object reload(Object key, Object oldValue) throws Exception {
        return CacheLoader.super.reload(key, oldValue);
    }

    @Override
    public CompletableFuture asyncReload(Object key, Object oldValue, Executor executor) throws Exception {
        return CacheLoader.super.asyncReload(key, oldValue, executor);
    }

我认为我必须从重新加载方法或咖啡因的构建方法中调用我的API。但是我不确定。我是新的缓存,因此需要您的帮助来实现此代码。

注意:我的应用程序是春季4.3.3.Release版本。

I have a requirement to use old/stale cache value if cache refresh is failed.
I have gone through the many examples on internet and decided to try with caffeine cache to implement this requirements(more specifically using refreshAfterWrite feature). I am able to cache the data using caffeine but not able to get old/stale value when cache refresh(rest api is failed) is failed.
I have used SimpleCacheManager(org.springframework.cache.support.SimpleCacheManager) and CaffeineCache.

**simpleCacheManager bean code** :

    <bean id="simpleCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches" ref="caffeineCaches" />
    </bean>

**caffeine cache** :

    @Bean
    public Collection<? extends org.springframework.cache.Cache> caffeineCaches(){
        Collection<CaffeineCache> caffeineCaches = new ArrayList<>();
        caffeineCaches.add(new CaffeineCache("pbdBankRegistry",
                Caffeine.newBuilder()
                        .refreshAfterWrite(2, TimeUnit.MINUTES)
                        .initialCapacity(1)
                        .maximumSize(2)
                        .recordStats()
                        .build(new CustomCacheLoader()),false));
        return caffeineCaches;
    }


  **CacheLoader Code :**

    public class CustomCacheLoader implements CacheLoader<Object, Object> {
    @Nullable
    @Override
    public Object load(Object o) throws Exception {
        return null;
    }

    @Override
    public Map loadAll(Set keys) throws Exception {
        return CacheLoader.super.loadAll(keys);
    }

    @Override
    public CompletableFuture asyncLoad(Object key, Executor executor) throws Exception {
        return CacheLoader.super.asyncLoad(key, executor);
    }

    @Override
    public CompletableFuture<? extends Map> asyncLoadAll(Set keys, Executor executor) throws Exception {
        return CacheLoader.super.asyncLoadAll(keys, executor);
    }

    @Nullable
    @Override
    public Object reload(Object key, Object oldValue) throws Exception {
        return CacheLoader.super.reload(key, oldValue);
    }

    @Override
    public CompletableFuture asyncReload(Object key, Object oldValue, Executor executor) throws Exception {
        return CacheLoader.super.asyncReload(key, oldValue, executor);
    }

I think i have to call my api from reload method or from build method of Caffeine. but i am not sure. I am new with the cache so here need your help to implement this code.

Note : My application is on spring 4.3.3.RELEASE version.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以为你会在 2025-02-14 18:12:46

在类似情况下,类似下面的事情对我有用:与 .build 提供函数。 /wiki/refresh“ rel =“ nofollow noreferrer”> https://github.com/ben-manes/caffeine/wiki/wiki/refresh ,通过实现 cacheloader 的对象,覆盖 load Reload 方法。

/**
 * @see https://www.javadoc.io/doc/com.github.ben-manes.caffeine/caffeine/latest/com.github.benmanes.caffeine/com/github/benmanes/caffeine/cache/CacheLoader.html#reload(K,V)
 */ 
class CacheLoader_keepOldIf<K,V> implements CacheLoader<K,V> {
  private Function<K,V> loadFn;
  private Function<V,Boolean> testNewFn;
  CacheLoader_keepOldIf(
    Function<V,Boolean> testNewFn, 
    Function<K,V> loadFn
  ){
    this.loadFn = loadFn;
    this.testNewFn = testNewFn; 
  }
  @Override
  public @Nullable V reload(K key, V oldValue) throws Exception {
    V newValue = loadFn.apply(key);
    return testNewFn.apply(newValue) ? oldValue : newValue;
  } 
  @Override
  public @Nullable V load(K key) throws Exception {
    return loadFn.apply(key);
  }
} 

LoadingCache<String, Object> myCache = Caffeine.newBuilder()
    .refreshAfterWrite(5, TimeUnit.SECONDS) 
    .build(new CacheLoader_keepOldIf<String,Object>(
        newValue -> newValue==null, 
        key -> someExpensiveCallReturningNullOnFailure()
    ))
;

该代码似乎是毫无必要的冗长,只是为了覆盖 reload 方法:其中一些无疑是我的错,有些可能是Java。但是它完成了工作:如果我的数据库呼叫失败,则返回null,并且使用了先前的缓存值。大概也可以在 load 方法中指定默认值,以防第一个填充缓存失败的调用。

(根据Ben Manes对问题的评论,我认为问题中 load 的覆盖物应返回某物而不是null以解决原始问题)。

Something like the below worked for me in a similar case: rather than supplying a Function to .build as per the examples at https://github.com/ben-manes/caffeine/wiki/Refresh, pass in an object that implements CacheLoader, and override both the load and reload methods.

/**
 * @see https://www.javadoc.io/doc/com.github.ben-manes.caffeine/caffeine/latest/com.github.benmanes.caffeine/com/github/benmanes/caffeine/cache/CacheLoader.html#reload(K,V)
 */ 
class CacheLoader_keepOldIf<K,V> implements CacheLoader<K,V> {
  private Function<K,V> loadFn;
  private Function<V,Boolean> testNewFn;
  CacheLoader_keepOldIf(
    Function<V,Boolean> testNewFn, 
    Function<K,V> loadFn
  ){
    this.loadFn = loadFn;
    this.testNewFn = testNewFn; 
  }
  @Override
  public @Nullable V reload(K key, V oldValue) throws Exception {
    V newValue = loadFn.apply(key);
    return testNewFn.apply(newValue) ? oldValue : newValue;
  } 
  @Override
  public @Nullable V load(K key) throws Exception {
    return loadFn.apply(key);
  }
} 

LoadingCache<String, Object> myCache = Caffeine.newBuilder()
    .refreshAfterWrite(5, TimeUnit.SECONDS) 
    .build(new CacheLoader_keepOldIf<String,Object>(
        newValue -> newValue==null, 
        key -> someExpensiveCallReturningNullOnFailure()
    ))
;

This code seems needlessly verbose just to override the reload method: some of this is doubtless my fault, and some possibly Java's. But it did the job: if my DB call fails, it returns null, and the previously cached value is used. It would presumably also be possible to specify a default value in the load method in case the first call to populate the cache fails.

(As per Ben Manes' comment on the question, I think the override of load in the example in the question should return something instead of null to fix the original issue).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文