2

I need to use several caches in my service for different uses. I'm looking for a way to separate their configurations like maximumSize and expireAfterWrite. I'm using Spring and Kubernetes, and in the deploy.yaml I have this:

spring:
  main:
    allow-bean-definition-overriding: true
  cache:
    type: CAFFEINE
    cache-names: cacheA, cacheB
    caffeine:
      spec: expireAfterWrite=1h,maximumSize=2000
  output:
    ansi:
      enabled: never

I want to create a new cache, cacheC, which will have a different configurations.

How can I do that? Thanks!

OLY
  • 65
  • 2
  • 7
  • 2
    The Spring authors were against that feature, but an [alternative adapter](https://github.com/stepio/coffee-boots) offers that functionality. – Ben Manes Aug 31 '20 at 15:21

1 Answers1

4

You can declare many cache configurations programmatically instead of using yaml.

Something like this:

@Configuration
@EnableCaching
public class CacheConfig {

    public static final String CACHE_A = "cacheA";
    public static final String CACHE_B = "cacheB";
    public static final String CACHE_C = "cacheC";

    @Bean
    public CacheManager cacheManagerTicker(Ticker ticker) {
       
       List<Cache> caches = new ArrayList<>();
       
       // Cache A
       caches.add(this.buildCache(CACHE_A, ticker, 2000L, 1L, TimeUnit.HOURS));
       
       // Cache B
       caches.add(this.buildCache(CACHE_B, ticker, 2000L, 1L, TimeUnit.HOURS));
       
       // Cache C
       caches.add(this.buildCache(CACHE_C, ticker, 3500L, 15L, TimeUnit.MINUTES));
       
       SimpleCacheManager cacheManager = new SimpleCacheManager();
       cacheManager.setCaches(caches);
       return cacheManager;
    }
    
    private CaffeineCache buildCache(String cacheName, Ticker ticker, Long maxSize, Long ttl, TimeUnit ttlUnit){
    
        Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder();

        // TTL
        if (ttl != null && ttl > 0 && ttlUnit != null){
            cacheBuilder.expireAfterWrite(ttl, ttlUnit);
        }
        
        // Max size
        if (maxSize != null && maxSize > 0){
            cacheBuilder.maximumSize(maxSize);
        }
        
        // Ticker
        cacheBuilder.ticker(ticker);
        
        return new CaffeineCache(cacheName, cacheBuilder.build());
    }
    
    @Bean
    public Ticker ticker() {
        return Ticker.systemTicker();
    }
    
}
Santiago Medina
  • 529
  • 2
  • 12
  • How to find the **cache size** for `cacheBuilder.maximumSize(maxSize);`. I am here trying to cache for 20 min. Is the size is in bite or byte or KB or GB or what? – Sathish Kumar k k Nov 28 '22 at 12:40
  • @SathishKumarkk the maximum cache size is in number of entries. – Santiago Medina Nov 29 '22 at 14:27
  • In my case I am going to case the method that returns a JWT token. So shall I have size as 1(one)? Since I am going to have only one entry and will update it after 20 min. – Sathish Kumar k k Nov 29 '22 at 15:13
  • @SathishKumarkk the maximumSize is a limit, is useful when you want to avoid the cache to grow to a dangerous size (in terms of available memory). But if you don't expect the number of entries to grow, you can skip setting a limit. Think if that JWT is one per application, or one per cache key (user, etc), and that will give you the expected number of entries. – Santiago Medina Nov 30 '22 at 02:54