views:

96

answers:

1

I have to cache an object hierarchy in-memory for performance reasons, which reflects a simple database table with columns (ObjectID, ParentObjectID, Timestamp) and view CurrentObjectHierarchy. I query the CurrentObjectHierarchy and use a hash table to cache the current parents of each object for quickly looking up the parent object ID, given any object ID. Querying the database table and constructing the cache is a 77ms operation on average, and ideally this refresh occurs only when a method in my database API is called that would change the hierarchy (adding/removing/reparenting an object).

Where is the best place for such a cache, if it must be accessed by multiple ASP.NET web applications, possibly running in different application pools?

Originally, I was storing the cache in a static variable in a C# dll shared by the different web applications. The problem, of course, is that while static variables can be accessed across threads, they cannot be accessed across processes, which is a problem when multiple web-apps are involved (possibly running in separate application pools). As a result... synchronized, thread-safe modifications to the object hierarchy cache in one application are not reflected in other applications, even though they are using the same code-base.

So I need a more global location for this cache. I cannot use static variables (as I just explained), session state (which is basically a per-user store), and application state (needs to be accessible across applications).

Potential places I've been considering are:

  • Some kind of global object storage within IIS itself, accessible from any thread in any application in any application pool (if such a place exists. Does it?)
  • A separate, custom web service that manages an exclusive cache.

Right now, I think the BEST solution is SQL CLR integration, because:

  • I can keep my current design using static variables
  • It's a separate service that already exists, so I don't have to write a custom one
  • It will be running in a single process (SQL Server), so the existing lock-based synchronization will work fine
  • The cache would be setting as close as possible to the data structures it represents!

I would embed the hierarchy-traversing methods in the SQL CLR DLL, so that I could make a single SQL call where I would normally make a regular method call. This all depends on SQL Server running in a single process and the CLR being loaded into that process, which I think is the case. What do you think of this? Can you see anything obviously wrong with this idea that I may be missing? Is this not an awesome idea?

EDIT: After looking more closely, it seems that different ASP.NET applications actually run in the same process, but are isolated by AppDomains. If I could find a way to share and synchronize data across AppDomains, that would be very very useful. I'm reading about .NET Remoting now.

A: 

Microsoft is working on a distributed caching framework: Velocity. However, the latest release is a CTP3 version, so it may not be production ready...

Ronald Wildenberg
Thanks for the tip. Although Velocity won't help me, because I'm working on a single machine. I also can't imagine it working quickly with any kind of concurrency model, since it's distributed... shared resources would have to be locked for indeterminate amounts of time across requests, which would defeat the purpose of a local, in-memory cache.
Triynko
You can also use it in a non-distributed, in-memory way, but that won't help you since you need cross process access to the cache. You do not have to distribute it.
Ronald Wildenberg