Search code examples
javacachingcache2k

Cache2K auto refreshAhead does'nt work as expected


I'm trying to create cache with auto refreshing elements using org.cache2k library. For example I define element loader with duration of 5 seconds. I set expire time 5 seconds. And I set keepDataAfterExpired and refreshAhead options to true.

First calling get method lasts approximatelly 5 seconds. It's ok. Then I expect that element will be expired and auto reloaded during next 15 seconds and second get will take element without delay. But my output is:

result

5011

result

5000

Second get as first lasts also 5 seconds as first. My goal is to make element refresh automatically and only first get would take delay. Is it reachable and how? Thank you.

    static String expensiveOperation(String name) throws InterruptedException {
        Thread.sleep(5000);
        return "result";
    }

    public static void main (String... args) throws InterruptedException {
        Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
                .expireAfterWrite(5000, TimeUnit.MILLISECONDS)    // expire/refresh after 5 seconds
                .keepDataAfterExpired(true)
                .refreshAhead(true)                       // keep fresh when expiring
                .loader(s->expensiveOperation(s))         // auto populating function
                .build();

        Instant i1 = Instant.now();
        System.out.println(cache.get("a"));
        Instant i2 = Instant.now();
        System.out.println(Duration.between(i1,i2).toMillis());

        Thread.sleep(15000);

        Instant i11 = Instant.now();
        System.out.println(cache.get("a"));
        Instant i22 = Instant.now();
        System.out.println(Duration.between(i11,i22).toMillis());

Solution

  • I found the answer in documentation about refreshAhead in Cache2k:

    "Once refreshed, the entry is in a trail period. If it is not accessed until the next expiry, no refresh will be done, the entry expires and will be removed from the cache. This means that the time an entry stays within the trail period is determined by the configured expiry time or the the ExpiryPolicy."

    So in my case 15 seconds is enough for entry to be auto refreshed and then expired and removed, so next get triggers a new load.