Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Creating cache for long running operations

 
Michal Glowacki
Ranch Hand
Posts: 114
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi,

on my website, in order to display data in convient way to customer, I have to run complex SQL queries. There is not much to improve, as the data set is being changed very often. Therefore I want to create "timed" cache, let's say data should be valid for 2 minutes. This is trival, however, if entry gets old and need recalculation (which last let's say 1,5-3 seconds) I have to solve the problem, what if 20 customers will trigger cached value recalculation.
Is there any design pattern for this purpose? I was thinking about some synchronized boolean, let's say "updating" and displaying old value to other customers, but I am simply scared of locks... Also there is a problem what if the value is not yet in cache at all, e.g. after server restart. In basic words, I am looking for solution to multiple updates of the same value, when it needs to be calculated. In the past I lost a lot of nerves when trying to use JBoss Cache for this purpose.
I would be very grateful for any tips from you.

Regards,
Michal
 
Tim Cooke
Sheriff
Pie
Posts: 2720
111
Clojure IntelliJ IDE Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Trying to roll your own caching framework is fraught with danger. I would recommend using an off the shelf solution such as ehcache
 
Michal Glowacki
Ranch Hand
Posts: 114
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok, I might use EHcache or Infinispan, but this not solve my problem of multiple running updates of value in cache when it's old.

If 100 customers will send request for the value inside time frame: from 1st request to old value to time it's updated, I got 100 queries running which will kill the performance / crash the site.
 
Tim Cooke
Sheriff
Pie
Posts: 2720
111
Clojure IntelliJ IDE Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Without knowing the specifics of your current implementation it's hard to know what to suggest as the best solution for your situation.

If it were me I would start by encapsulating my database table access into a single point using the Repository Pattern (see Fowler's Patterns of Enterprise Application Architecture) and then implement my cache in there. If you route all read and write access through this repository then your cache becomes much easier as you don't have to constantly watch the db table for changes made elsewhere. This is ok as long as the db table is exclusively used by your single application. If you have a shared schema between systems then that's a whole other smell of its own, one which caching alone will not help you with.
 
Jayesh A Lalwani
Rancher
Pie
Posts: 2756
32
Eclipse IDE Spring Tomcat Server
  • 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You could have 2 caches. One that is read only and is displayed to the user. Other one is updated in the background . When its time to show the updated data to the user, swap the caches. This way you are locking the caches only when you swap them.
 
Frank Pavageau
Greenhorn
Posts: 11
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can use Guava's LoadingCache, which will only compute the value once even if there are concurrent requests for the same (missing) key.
 
ejaz khan
Greenhorn
Posts: 5
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If multiple business components changing the database than situation is not easy
You can use dirty bit option in the database against each record. Any component which is making any DML should set the value to '1'
And after 2 minutes you can check only those records which are having dirty bit = '1'
You will refresh your cache and set the dirty bit to '0'
Maintaining two copies of Cache is also a good option
 
Winston Gutkowski
Bartender
Pie
Posts: 9490
50
Eclipse IDE Hibernate Ubuntu
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michal Glowacki wrote: I would be very grateful for any tips from you.

Well, like Tim, without knowing more specifics, it's difficult to advise on what the best solution is, but I would definitely guard against statements like "there is not much to improve" - particularly when you clearly have a problem - because it sounds like you're saying: "I want a solution, but I'm not prepared to do a, b, c...".

You might want to look at my quote at the bottom, because that's exactly the sort of thinking it's referring to.

It sounds to me like you need to analyse your transactions thoroughly. Only then will you be in a position to:
(a) Ask for advice.
(b) Come up with a solution from the answers you're given.

Winston
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic