2

I have configured my cache as follows:

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean(name = "caffeineCachingProvider")
    public CachingProvider caffeineCachingProvider() {
        return Caching.getCachingProvider("com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider");
    }

    @Bean(name = "caffeineCacheManager")
    public JCacheCacheManager getSpringCacheManager() {
        CacheManager cacheManager = caffeineCachingProvider().getCacheManager();
        CaffeineConfiguration<String, List<Product>> caffeineConfiguration = new CaffeineConfiguration<>();
        caffeineConfiguration.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new AccessedExpiryPolicy(new Duration(TimeUnit.MINUTES, 60))));
        caffeineConfiguration.setCopierFactory(Copier::identity);
        cacheManager.createCache("informerCache", caffeineConfiguration);
        return new JCacheCacheManager(cacheManager);
    }
}

Also I have the @Service that uses it in following way:

@Service
public class InformerService {

    @CacheResult(cacheName = "informerCache")
    public List<Product> getProducts(@CacheKey String category, @CacheKey String countrySign, @CacheKey long townId) throws Exception {
        Thread.sleep(5000);
        // do some work
    }
}

So I have the next behavior.

  1. When I'm calling the service method first time it takes 5 seconds then doing some work as expected.
  2. Calling method the second time with same parameters - > caching works -> returns result immediately
  3. Calling the third time with same parameters again results in Thread.sleep

And all over again.

How to solve this ? Is that the issue about proxying ? What did I miss ?

marknorkin
  • 3,904
  • 10
  • 46
  • 82
  • Perhaps there is a bug in the cache's expiration logic? The TCK doesn't provide much coverage here, unfortunately, so more tests are desirable for the JCache adapter. Can you wrap this into a sample so that I can debug it with you? Also note that version [2.0.3](https://github.com/ben-manes/caffeine/releases) fixed some JCache issues. – Ben Manes Jan 15 '16 at 17:40
  • 1
    I think you found a bug. When the `access time` is [updated after a get](https://github.com/ben-manes/caffeine/blob/master/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheProxy.java#L173), the new time set to the current millis and [not adjusted](https://github.com/ben-manes/caffeine/blob/master/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheProxy.java#L1065) by the expiry duration. I'll fix this and add some additional tests over the weekend. Sorry about that. – Ben Manes Jan 15 '16 at 18:27
  • @BenManes currently we are using version 2.0.3 of caffeine lib – marknorkin Jan 15 '16 at 20:47
  • @BenManes that's cleared something, waiting for a bugfix. thank you for replying – marknorkin Jan 15 '16 at 20:48
  • 1
    I pushed a fix (available as a snapshot). I'll spend time over the weekend to add JCache tests and try to have a release out Sunday night. – Ben Manes Jan 16 '16 at 01:07

1 Answers1

3

As discussed in the comments, this was a bug in the JCache adapter. Thank you for letting me know about this problem. I released version 2.1.0 which includes this fix. That release also includes friendlier initial settings for CaffeineConfiguration which you identified in another post.

While the core library is heavily tested, the JCache adapters relied too heavily on the JSR's TCK (test compatibility kit). Unfortunately that test suite isn't very effective, so I added tests to help avoid these types of mistakes in the future.

This issue only occurred in JCache because its version of expiration is not supported by Caffeine's core library. Caffeine prefers to use an O(1) design that eagerly cleans up expired entries by using fixed durations. JCache uses per-entry lazy expiration and the specification authors assume a capacity constraint is used to eventually discard expired entries. I added a warning to the documentation about this feature, as it could be error prone. While none of the other JCache implementations go beyond this, a pending task is to decide on a mechanism to help mitigate this JCache design flaw.

Thanks again for reporting this issue. As always, feel free to reach out if you have any other issues or feedback to share.

Community
  • 1
  • 1
Ben Manes
  • 9,178
  • 3
  • 35
  • 39