Data Caching Implementation

Posts   
 
    
uydo
User
Posts: 43
Joined: 09-Dec-2003
# Posted on: 18-Jun-2004 17:47:14   

Hi all,

We are developing a web project, in which we have a user control to read data from DB whenever every page is requested. Every once in a while when an authorized user changes the data in that user control, it has to be loaded to all current users that are online on their next clicks. Since it's not very often to get this thing(the data) changed, I think that we should use some cache technique to cache the data for a better performance. I tried to google & msdn but all the info there are very general so I decided to post it here to get feedbacks from the valued llbl club members.

Thanks all and have a good weekend. Uy

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 18-Jun-2004 19:46:58   

Hmmm...methinks the MS Caching Application Block would fit here. Check this link out: MS Patterns and Practices Caching Application Block

Tons of great stuff from the Patterns and Practices team over at Microsoft.

Jeff...

(Anyone want to comment on my erudite and judicious use of the [url]tag? I RTFM!) wink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 18-Jun-2004 20:03:44   

Splendig work you did there, Jeff, with that URL wink stuck_out_tongue_winking_eye

On topic: caching can be as easy as you make it to be. The more you want it to be transparent, the more work it takes.

A simple hashtable with cached objects and a hashtable with flags signalling the validity of the cached objects can already help. Set the flag to false when you for example change an entity cached and the next time you check the flags, you see you have to reload hte object instead of using the cached one.

But you can also use the cache application block. It will offer you good functionality without much hassle.

Frans Bouma | Lead developer LLBLGen Pro
uydo
User
Posts: 43
Joined: 09-Dec-2003
# Posted on: 18-Jun-2004 22:36:52   

Thanks Jeff for the good guide. Seems like I have to install it on the server where the app runs.. In my situation, my client wanted to use a web hosting service, so I don't know if I can afford extra installations or not. I'll save it for our inhouse projects!

Frans, do you have a few lines of code demonstrating what you've said? I'd be more than happy to start with an example.simple_smile

Thanks guys.

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 19-Jun-2004 03:57:18   

Hey, if it'll help, I believe it's just an xcopy/FTP deploy to the /bin directory if you do a file reference; otherwise it just shows up as another project in your solution. The learning curve on the other hand is another matter...it may be overkill for what you're doing.

Jeff...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 19-Jun-2004 10:31:12   

uydo wrote:

Frans, do you have a few lines of code demonstrating what you've said? I'd be more than happy to start with an example.simple_smile

Create an enum with the various entities you want to cache. these are indices for your flags and cached objects.

then create 2 hashtables. One for the cached objects, and the other one for the flags. The flag-hashtable gets for each enum value a 'false'.

When you want to use an object that can be cached, use its enum value and determine if its flag in the flag-hastable is false. If so, load it from the DB and store it in the object-hashtable with the same enum value as key. Set the flag to 'true'. If the flag was true, simply grab the object from the object-hashtable, using the enum value.

That's about it simple_smile

Frans Bouma | Lead developer LLBLGen Pro
uydo
User
Posts: 43
Joined: 09-Dec-2003
# Posted on: 25-Jun-2004 17:17:50   

Frans, I dont know if its right or not. I implemented those 2 Hashtables as protected, then I exposed the rows as separate public properties and it worked for me. See code & please comment:


protected static Hashtable  CachedObjects = new Hashtable();
protected static Hashtable  CachedFlags = new Hashtable();
public enum EnumCachedIndices {agentName,agentAddress,agentBG,agentLogo};
.....
public string AgentName
{
    get{
      if (AgentNameFlag)    {
       CacheManager.CachedObjects[EnumCachedIndices.agentName] = GetAgentName();
    AgentNameFlag = false;
    
              return CacheManager.CachedObjects[EnumCachedIndices.agentName].ToString();
        }
    set
       {
         CacheManager.CachedObjects[EnumCachedIndices.agentName] = value;
         AgentNameFlag = true;
       }

}

protected bool AgentNameFlag
{
get {
       if (CacheManager.CachedFlags[EnumCachedIndices.agentName] != null) {
        return (bool)CacheManager.CachedFlags[EnumCachedIndices.agentName];
       }
      else{             
       CacheManager.CachedFlags[EnumCachedIndices.agentName] = true;
       return (bool)CacheManager.CachedFlags[EnumCachedIndices.agentName];
     }
set{
   CacheManager.CachedFlags[EnumCachedIndices.agentName] = value;
 }
}


My question is, is it good to expose the whole Hashtable CachedObjects ? If this is the case, then what do I do to accomplish this?

Thanks for all inputs.

P.S: I know its another friday, but a job is a job is a job! ah well,

~ Uy

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 28-Jun-2004 10:52:42   

A 'static' declared hashtable is vulnerable to threading issues. It's unlikely perhaps, but better not declare it as static or add lock() statements to prevent duplicate writes at the same time.

Frans Bouma | Lead developer LLBLGen Pro
uydo
User
Posts: 43
Joined: 09-Dec-2003
# Posted on: 29-Jun-2004 16:53:19   

Frans, If I should not define these Hashtables as static, what's the alternative way(s) of approaching this? I have to reference all rows in this Hastable across the pages, and I'd like to try something with Cache object, if you think its the right way to do...

Thanks so much for your advice, & still waiting for others to come.simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39615
Joined: 17-Aug-2003
# Posted on: 29-Jun-2004 21:54:03   

Well, staticly defining the hashtables is ok, as long as you remember that you have to lock the access point to the hashtable simple_smile . Because if two threads start to write the same value, it will become a mess, so access has to be controlled sequentially.

object key = new object(); lock(key) { // here is your hashtable access code which is now sequential }

Frans Bouma | Lead developer LLBLGen Pro