DocJones
DocJones

Reputation: 677

Caffeine Springboot integration

we are using caffeine to replace the ConcurrentHashMap cache, which is default in current springboot. We are dynamically creating caches using the @Cacheable(cacheNames = { "..." }) annotation.

I am trying to set the recordStats property, since we are using the springboot actuator package to monitor various aspects of our applications.

I tried to set spring.cache.caffeine.spec=expireAfterAccess=3600s,recordStats in application.properties, which does not work.

Setting it in a @Configure class did not work either:

@Configuration
public class CacheConfig {

  @Bean
  public CacheManager cacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager();
    cacheManager.setCacheSpecification("expireAfterAccess=3600s,recordStats");
    return cacheManager;
  }
}

The cache statistics does not appear in the /actuator/cache/{caches} endpoint or in our springboot-admin server.

Taking from the current api documentation, i found:

The string syntax is a series of comma-separated keys or key-value pairs, each corresponding to a Caffeine builder method.

initialCapacity=[integer]: sets Caffeine.initialCapacity.

...

recordStats: sets Caffeine.recordStats(). 

Durations are represented by an integer, followed by one of "d", "h", "m", or "s", representing days, hours, minutes, or seconds respectively. There is currently no syntax to request expiration in milliseconds, microseconds, or nanoseconds.

Whitespace before and after commas and equal signs is ignored. Keys may not be repeated; it is also illegal to use the following pairs of keys in a single value:

maximumSize and maximumWeight
weakValues and softValues 

And the relevant point:

CaffeineSpec does not support configuring Caffeine methods with non-value parameters. These must be configured in code.

Is there no possibility to achieve my task?

thanks

Upvotes: 1

Views: 6430

Answers (2)

stepio
stepio

Reputation: 905

You can define bean for you cache manually, e.g.

@Bean
public Cache recorded() {
    return new CaffeineCache("recorded", Caffeine.newBuilder()
            .recordStats()
            .build());
}

This bean will be picked up by Spring Boot and you will be able to use @Cacheable("recorded") in your code (note the matching cache names).

Also my pet project for Caffeine and Spring Boot may be useful for you as well: https://github.com/stepio/coffee-boots

This exact recordStats() setup functionality is not tested there, but bug reports and PRs are always appreciated.

P.S.: Related question: Dynamically toggling recording stats on Caffeine Cache

Cheers!

Upvotes: 8

DocJones
DocJones

Reputation: 677

I managed to get it work. Here is the code:

@Configuration
public class CacheConfig {

  @Bean
  public CacheManager cacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager("cache1",
        "cache2", "cache3");
    cacheManager.setCacheSpecification("recordStats");
    return cacheManager;
  }
}

still with the downside, that the cache names must match those in the @Cacheable(cachenames={"..."}) annotation

Upvotes: 4

Related Questions