-
1. Re: Recompute expired cached value keeping old value till done
vmassol Mar 28, 2016 9:16 AM (in response to vmassol)Could I be hitting [ISPN-694] Create expiration notification for in-memory cache entries - JBoss Issue Tracker?
Is there another better way to implement my use case?
Thanks
-
2. Re: Recompute expired cached value keeping old value till done
vmassol Mar 28, 2016 11:10 AM (in response to vmassol)Note that I have now tried with 8.2.0.Final and I have the same issue.
-
3. Re: Recompute expired cached value keeping old value till done
vmassol Mar 29, 2016 5:04 AM (in response to vmassol)ok so I was using the wrong event. It works better with @CacheEntryExpired.
Of course I'm now hitting the problem of not having the lock when I try to put back the cache entry in the cache before starting the async recomputation.
Any idea for that part?
Thanks
-
4. Re: Recompute expired cached value keeping old value till done
william.burns Mar 30, 2016 11:57 AM (in response to vmassol)Vincent Massol wrote:
ok so I was using the wrong event. It works better with @CacheEntryExpired.
Of course I'm now hitting the problem of not having the lock when I try to put back the cache entry in the cache before starting the async recomputation.
Any idea for that part?
Thanks
So there could be a few things you might be able to do, but I think we may need to know exactly what you are trying to do. It sounds like you are using expiration to basically cache a value in memory for the lifespan and then get the updated value after the lifespan occurs, keeping a value in memory and updating every so often.
If this it the use case I would recommend you add your own CacheLoader (note not CacheWriter) implementation that does this computation. Then you can easily use expiration or even better in my opinion eviction so that you can have the most recently used values in memory all the time.
But in this case if an entry expires or is evicted it won't be recomputed (doesn't take up memory even) until you have another get on this key and then the loader can do the recomputation and then ISPN takes the result of the loader writes it to the cache and returns it to the caller.
-
5. Re: Recompute expired cached value keeping old value till done
vmassol Mar 31, 2016 3:52 AM (in response to william.burns)Thanks William for the replly (still trying to process and understand it, I'm not familiar with CacheLoader).
Here's my use case (note that I've also created https://issues.jboss.org/browse/ISPN-6443).
- I have some lenghty computations that gives results that I cache for some time (lifespan)
- I don't want users to incur the wait before the computation is finished so I need to always have some value to return immediately to them, and in parallel, when the lifespan is reached, recompute the results asynchronously and overwrite the existing values in the cache
More specifically, this is for a wiki (XWiki, http://xwiki.org), we have a {{cache}} macro (http://extensions.xwiki.org/xwiki/bin/view/Extension/Cache+Macro) that ca be used in wiki pages. Inside that macro users can use scripting macros to perform various API calls and computations. The {{cache}} macro caches the result of rendering what's inside it. For example:
{{cache}}
{{velocity}}
$xwiki.someLengthyCall()
{{/velocity}}
{{/cache}}
My goal is to never have users to wait for the rendering to be done and instead to always return a stored result from the cache and to recompute the rendering asynchronously when the lifespan is reached.
Do you still think the best solution is having a custom CacheLoader? An idea I had (hence the jira issue) would have been to be able to cancel the expiration event in my listener so that the value stays in the cache for another round and in parallel I would have started a recomputation thread to compute a new value. My issue ATM is that I can't put back the cache value since the cache has a lock on it.
Thanks a lot for your help.
-
6. Re: Recompute expired cached value keeping old value till done
william.burns Mar 31, 2016 3:28 PM (in response to vmassol)In the case of your computation taking a long time and you can't block the reader for that duration, I would say using the CacheLoader approach may not work out for you. With the cache loader approach the user would be blocked while the value is recomputed.
To be honest given your use case you may want to do this yourself. Unfortunately expiration is really about removing a value and returning null to the user asap. Cancelling an expiration imo doesn't really make as much sense.
What you could do is store some sort of timestamp along with your value. Then when you retrieve your value you can check this and if needed fire off an async operation to replace this value and return the current one to the caller immediately. You can even use the new FunctionalMap [1] to help you out here by using the eval method and writing a MetaParam.Writable instance if you don't want to have a wrapper object.