What I am trying to accomplish is to set up both TTL (time to live) and TTI (time to idle) for a cache, so that the key either expires after TTL time or it can be expired earlier in case in hasn't been accessed for TTI period.
In Ehcache 2 it was possible with the following configuration:
<cache name="my.custom.Cache"
timeToIdleSeconds="10"
timeToLiveSeconds="120">
</cache>
In Ehcache 3 the analogous configuration block looks like the following:
<cache alias="my.custom.Cache">
<expiry>
<tti unit="seconds">10</tti>
<ttl unit="minutes">2</ttl>
</expiry>
</cache>
The problem is that such configuration is considered invalid since ehcache.xsd states that there should only be one option under expiry tag (either tti or ttl, but not both).
As mentioned by Louis Jacomet on the mailing list:
In order to achieve what you want, you need to create a custom Expiry, which you can do with the Expirations.builder() that was introduced in 3.3.1, or with a custom implementation of the Expiry interface.
Note however that your explanation of what the expiration did in Ehcache 2 is slightly incorrect. When you combine TTL and TTI, the element remains valid for the whole TTL whether it is accessed or not. However, if it is accessed close to the end of the TTL period, the last access time + TTI can make it stay for longer in the cache. And if it is access again during that period, the last access time is updated again thus extending the life of the mapping.
The way Expiry works in Ehcache 3 is slightly different, as effectively we compute an expiration time each time the mapping is created, accessed or updated. This is done to reduce overhead in stored mappings.
So if you configure your Expiry with getExpiryForCreation returning 120 seconds but getExpiryForAccess returning 10 seconds, a created but never access element will be considered expired after 120 seconds. While a created but accessed element will be considered expired 10 seconds after the last access, even if that time is still within the 120 seconds.
TTI is really a weird concept when you think about it, that we kept for JCache compatibility, but which is effectively closer to eviction than expiration. Because what does it mean for the freshness of a value that it is being read? While it indeed means this is a useful value in the cache that should not be evicted.
And in XML, you cannot use the tti and ttl shortcut in combination. But you can configure an expiry by fully qualified class name. We should consider extending the XML system so that you can do some equivalent of the added builder in code.
Related
The class DefaultJWKSetCache of nimbus-jose-jwt has two fields, lifespan and refreshTime.
From Java docs -
lifespan - The lifespan of the cached JWK set before it expires,
negative means no expiration.
refreshTime - The time after which the
cached JWK set is marked for refresh, negative if not specified.
Should be shorter or equal to the lifespan.
What is the difference between these two.
Does it mean that,
after the lifespan expiry the cached JWK set will be evicted and loaded again from jwks remote url (saying remote url as i am using RemoteJWKSet).
and after the refresh expiry the existing JWK set will be updated with the keys retrieved from remote url.
But i don't understand the practical difference between the two. Both seem to be doing same. Can some one explain the details with more granularity and any example.
Edit - if i give no expiry for lifespan, and 1 hour expiry for refreshTime, am i guaranteed that my keys will be updated every one hour.
The lifespan is the time after which the DefaultJWKSetCache will evict cached JWKSet. I.e., after lifespan time units passed since the cache was populated the calls to JWKSetCache.get() will always return null until new JWKSet is stored to the cache.
The refreshTime is the time that impacts value returned by JWKSetCache.requiresRefresh() method. After refreshTime time units passed since the cache was populated this method will return true, otherwise, it will return false. This setting does not impact cache behavior in any way.
The RemoteJWKSet uses the value returned by JWKSetCache.requiresRefresh() to re-download JWKSet from remote URL before the cache is actually expired. This is why documentation recommends to set refreshTime to a lesser value than lifespan.
Currently, RemoteJWKSet triggers download of remote JWKSet when either lifespan or refreshTime has passed (see this line.) Hence, there is not much difference in setting either one of these as of today. I guess some more complex logic can be potentially implemented having these two values separate.
We are using Redission client for java to get the data from redis but object gets deleted from collection due to TTL.
Example
We are trying the below approach to get the data from Redis with TTL.
final RList rList = client.getList(getEnvCacheKey(cacheKey));
rList.expire(7L, TimeUnit.SECONDS);
rlist.add("Value1");
rlist.add("Value2");
assertThat(rList).containsOnly("Value1", "Value2"); // This condition is true until 7 seconds
Now after 7 seconds
assert rlist.size() == 2 condition becomes false since object references are deleted due to TTL.
Due this we landed up in a production issue. Is there any way we can retain the objects even after TTL? Any sort of help will be appreciated.
The TTL(Time-To-Live) itself sets the expiration of a particular key after which the key can no longer be retrieved. If you want to keep the key in the memory you could simply skip setting rList.expire(7L, TimeUnit.SECONDS); altogether (infinite expiration).
In case you want to extend expiration, you can do so by repeating the expire command. It is also possible to remove the TTL altogether this way, although I could not tell you how to do it specifically with the Redisson.
As for the expired keys, Redis clears them 10 times a second (according to this documentation), so I don't think that you can (consistently) recover the values within the expired keys.
My general advice would be to take a step back and look at your system design. In case you are missing the expired keys, maybe this part of the product should get an extended TTL/no TTL/periodical TTL refresh
Intro
This is regarding infinispan cache but I think this is a generic enough question.
In my infinispan cache Im inputting items into cache using putIfAbsent method and removing them with remove method. (jboss doc here)
Basic Behavior
I can put items into my cache and remove items from cache using a id. But if I do not remove the cache item explicitly, infinispan will remove it automatically after the specified life span is passed.
In my remove method I run some custom code before removal.
But when I am not invoking the remove method, infinispan remove the cache entry due to the expiry of provided life span.
In that automatic removal scenario I cannot run my custom code because it happens under the hood. (by infinispan). So what is the possible way? Following code will explain this a bit more hopefully.
I belive I am clear enough. Please give me some insight.
Thank you.
void putToCache(String id){
myCache.putIfAbsent(id,value,LIFESPAN_DURATION,timeUnit);
}
void removeFromCache(String id){
//MY CUSTOM CODE - WANT TO RUN THIS IN LIFE SPAN DURATION EXPIRY ALSO
myCache.remove(id);
}
Before going into the answer I want to clarify between eviction and expiration.
Eviction
Eviction is when an entry is removed from the in memory container due to it growing outside of the configured maximum size (max-entries). Eviction can only be enabled at configuration time and is not controlled at runtime which Expiration can be, please see here. Note that eviction never removes an entry from a store if you have one configured, thus you don't just lose an entry due to having too many if you don't want to.
Infinispan 7 and older versions have a listener for Eviction as you already found, and the event raised would be this one.
Expiration
Expiration defines an entry being removed after a period of inactivity or a set duration. This can be configured through configuration or you can override the configured value by using the API as you did your in example.
Now to answer your question, an Infinispan Expiration event was added with Infinispan 8. It is detailed more here. Note an important piece is that the expiration event will be fired holding the lock for the key that is expiring (unless your listener is defined as async). This is important to guarantee proper ordering.
Also you should keep in mind that expiration events are not guaranteed to fire exactly when the entry expires. Rather the event is only fired upon accessing said expired entry or if the expiration reaper thread finds the expired entry. The expiration reaper defaults to run every minute, you can disable this or change the time by changing the expiration interval configuration setting.
I would like to use Ehcache for the following task:
There's a routine that can be executed only n times a day. Each time it's invoked, a counter in the database is decreased. When it reaches 0, this fact is denoted in a shared hash map (filed under the current date), and there's no need to contact the database until the end of day. The database counter is reset to n at midnight by an asynchronous task, the hash map does not have appropriate entry for the new date, and database polling resumes.
Now I'd like to implement this behaviour in Ehcache, because we use it already for other caches, and because I'd like to be able to turn off all caching in one place. This poses the following problems:
The condition for cache activation is known only inside the #Cacheable method (when it's discovered that the DB counter is zero). This probably rules out declarative cache specification, correct?
The time to live needs to be specified as a point in time, not as duration. Is this possible?
You will probably have to implements eviction policy if you want to do that with ehcache.
see here : http://ehcache.org/documentation/apis/cache-eviction-algorithms#plugging-in-your-own-eviction-algorithm
When using ehcache, is there a way to expire cache on certain time of the day?
Thanks,
Lawardy
There is no such functionality out-of-the-box. You need an external solution like Quartz, also from Terracotta umbrella.
In fact, even normal timeToLive parameter does not remove element in question after this time elapses, because this would required additional thread. Instead the item is removed when new one is to be added which takes its place.