0

I want to provide a method with the signature-

`public void addObjectToCacheWithExpiry(CaffeineCacheManager caffeineCacheManager, String cacheName, String key, Object value, long duration, TimeUnit timeUnit)`

So that I can put a value inside the specific cache with the duration passed as an arg.

Some explanation was offered here by Ben Caffeine Cache - Specify expiry for an entry

`.  @Override
    public void addObjectToCacheWithExpiry(CaffeineCacheManager caffeineCacheManager, String cacheName, String key, Object value, long duration, TimeUnit timeUnit) {
        CaffeineCache caffeineCache = (CaffeineCache) caffeineCacheManager.getCache(cacheName);
        Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
        Policy.VarExpiration varExpiration = (Policy.VarExpiration) nativeCache.policy().expireVariably().get();
        varExpiration.put(key, value, duration, timeUnit);`
    }

I couldn't follow the whole thing. It mentions that we can use cache.policy() to get Policy.VarExpiration interface which provides access to the method I needed. To that end, I added the following code-

In principle this is what I wanted. However, when I get the nativeCache object it doesn't show up with a policy(policy = null). This prevents me from using it to put object since it just returns NPE. How should I tackle this? null policy for empty map

Adding the config for CaffeineCache-

`   `@Bean
    public CaffeineCacheManager caffeineCacheManager(Caffeine caffeine){
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        caffeineCacheManager.setCaffeine(caffeine);
        return caffeineCacheManager;
    }

    @Bean
    public Caffeine CaffeineCacheConfig() {
        return Caffeine.newBuilder()
                .expireAfterWrite(5, TimeUnit.MINUTES)
                .initialCapacity(1000)
                .maximumSize(1200);
    }`
`
xyz
  • 1
  • 1
  • Did you try calling the `policy()` method? The field is lazily allocated, just like how `HashMap` lazily initializes its `keySet` and related views. – Ben Manes Jun 13 '23 at 19:49
  • I think I was able to resolve this. I wasn't implementing the expireAfter property. Once I did, it started working. From documentation as well it mentions that these specific policies are accessible if you support them at the time of construction. I am adding my own answer to this question – xyz Jun 13 '23 at 20:27

1 Answers1

0

I was able to get it to work. From the documentation -

/** * Returns access to perform operations based on the variable expiration policy. This policy * determines that an entry should be automatically removed from the cache once a per-entry * duration has elapsed. *

* If the cache was not constructed with variable expiration or the implementation does not * support these operations, an empty {@link Optional} is returned. * * @return access to low-level operations for this cache if a variable expiration policy is used */ @NonNull

Based on this, I removed expireAfterWrite property and instead implemented expireAfter. I was able to test that dynamic ttl with VarExpiration.put was working fine. I will update this answer after I have tested that a default of 5 min was also being applied in case of a missing ttl.

@Bean
public <K,V> Caffeine<K, V> CaffeineCacheConfig() {
    return Caffeine.newBuilder()
        .initialCapacity(1000)
        .expireAfter(new Expiry<K , V>() {
            public long expireAfterCreate(K key, V graph, long currentTime) {
                // Use wall clock time, rather than nanotime, if from an external resource
                //return TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_IN_SECONDS);
                log.info("Expire after create");
                return TimeUnit.SECONDS.toNanos(5 * 60);
            }

            public long expireAfterUpdate(K key, V graph,
                long currentTime, long currentDuration) {
                return currentDuration;
            }
    
            public long expireAfterRead(K key, V graph,
                long currentTime, long currentDuration) {
                return currentDuration;
            }
        }
    ).maximumSize(1200)
     .evictionListener(((key, value, cause) -> {
          log.info("evicted key, value, cause : {} {} {}", key, value, cause);
      })).removalListener(((key, value, cause) -> {
          log.info("removed key, value, cause : {} {} {}", key, value, cause);
      }));
}
ahuemmer
  • 1,653
  • 9
  • 22
  • 29
xyz
  • 1
  • 1