Ben Foster
Ben Foster

Reputation: 34830

Synchronizing local cache with external application

I have two separate web applications:

  1. The "admin" application where data is created and updated
  2. The "public" application where data is displayed.

The information displayed on the "public" changes infrequently, so I want to cache it.

What I'm looking for is the "simplest possible thing" to update the cache on the public site when a change is made in the admin site.

To throw in some complexity, the application is running on Windows Azure. This rules out file and sql cache dependencies (at least the built in ones).

I am running both applications on a single web role instance.

I've considered using Memcached for this purpose. but since I'm not really after a distributed cache and that the performance is not as good as using a memory cache (System.Runtime.Caching) I want to try and avoid this.

I've also considered using NServiceBus (or the Azure equivalent) but again, this seems overkill just to send a notification to clear the cache.

What I'm thinking (maybe a little hacky, but simple):

  1. Have a controller action on the public site that clears the in memory cache. I'm not bothered about clearing specific cached items, the data doesn't change enough for me to worry about that. When the "admin" application makes a cache, we make a httpwebrequest to the clear cache action on the public site.
  2. Since the database is the only shared resource between the two applications, just adding a table with the datetime of the last update. The public site will make a query on every request and compare the database last update datetime to one that we will hold in memory. If it doesn't match then we clear the cache.

Any other recommendations or problems with the above options? The key thing here is simple and high performance.

Upvotes: 1

Views: 395

Answers (3)

Ben Foster
Ben Foster

Reputation: 34830

In the end I used Azure Blobs as cache dependencies. I created a file change monitor to poll for changes to the files (full details at http://ben.onfabrik.com/posts/monitoring-files-in-azure-blob-storage).

When a change is made in the admin application I update the blob. When the file change monitor detects the change we clear the local cache.

Upvotes: 0

knightpfhor
knightpfhor

Reputation: 9409

Having a public controller that you can call to tell the site to clear its cache will work as long as you only have one instance of the main site. As soon as you add a second instance, as calls go through the load balancer, your one call will only go to one instance.

If you're not concerned about how soon the update makes it from the admin site to the main site, the best performing and easiest (but not the cheapest) solution is to use the Azure AppFabric Cache and then configure it to use a a local (in memory) cache with a short-ish time out (say 10 minutes).

The first time your client tries to access an item this would be what happens

  1. Look for the item in local cache
  2. It's not there, so look for the item in the distributed cache
  3. It's not there either so load the item from persistent storage
  4. Add the item to the cache with a long-ish time to live (48 hours is the default I think)
  5. Return the item

Steps 1 and 2 are taken care of for you by the library, the other bits you need to write. Any subsequent calls in the next X minutes will return the item from the in memory cache. After X minutes it falls out of the local cache. The next call loads it from the distributed cache back into the local cache and you can carry on.

All your admin app needs to do is update the database and then remove the item from the distributed cache. The next time the item falls out of the local cache on the client, it will simply reload the data from the database.

If you like this idea but don't want the expense of using the caching service, you could do something very similar with your database idea. Keep the cached data in a static variable and just check for updates every x minutes rather than with every request.

Upvotes: 1

Jeremy McGee
Jeremy McGee

Reputation: 25210

1., where you have a controller action to clear the cache, won't work if you have more than one instance; otherwise, if you know you have one and only one instance, it should work just fine.

2., where you have a table that stores the last update time, would work fine for multiple instances but incurs the cost of a SQL database query per request -- and for a heavily loaded site this can be an issue.

Probably fastest and simplest is to use option 2 but store the last update time in table storage rather than a SQL database. Reads to table storage are very fast -- under the covers it's a simple HTTP GET.

Upvotes: 1

Related Questions