views:

139

answers:

5

I have an httpmodule that reads from a csv file for redirection rules.

However, since it's an httpmodule and it is checking on every request, I obviously don't want to read the file every time.

What are some strategies to cache the rules (in an in Array) so that I do not have to read the file on every request?

Update: Using .NET 2.0

A: 

How about a Dictionary? You can just grab the one you want using dict[rule]. Or is it more complicated than that? Convert the csv to XML and use XQueryXPath searches?

serialhobbyist
It's not data conversion that this question is about, but data storage.
Robert Koritnik
Yeah, misread the post.
serialhobbyist
A: 

The Application storage is the appropriate place to put this assuming that all users will be redirected in the same manner. The Session storage stores information with the context of the current user and is only share for that user. The Application storage functionality keeps the information so that it can be globally shared amongst All users, and guests.

If this information is quite large (>60mb+ or 1000s+ of objects) you might want to consider a serious enterprise level caching component (similar to JCS/EhCache [but for .net])

monksy
A: 

We do this by storing the rules (or similar) in the Application state.

We load the values in Session_Start (with a test to ensure that we only do it once) - I have a comment in Application_Start that states: "moved to session start because it seems to work better"

Something like this:

Application.Lock();
// Only load the rules if we haven't already
if (Application["RulesCache"] == null)
{
    List<Rule> rules = LoadRules();
    Application["RulesCache"] == rules;
}
Application.Unlock();

We're actually a little more sophisticated than this - but the basic premise is valid.

Pragmatically, you'd want to encapsulate the load into a separate routine and probably provide a mechanism to update the cache without having to restart the application

Murph
+3  A: 

Use Cache with file dependency

On cache miss you will read your values and also transform them into a list of certain object types and cache them. The benefits:

  • unified storage for all users, because they all these values since you're using HttpModule
  • automatic memory utilisation management - cache is fast and may get discarded when server is low on memory
  • file dependency cache is great when you change the file and your cache will automatically get invalidated and read anew in the first request from the newly changed file so you don't have to restart you application or do some other tricks to refresh cached values
  • fast data reads - if you also convert CSV data on file read you gain a lot of time because you will only parse it once so all subsequent data reads will take much less time than if you stored CSV raw data only and parse on every data read

Additional note
It should be noted as well that OS caches files as well. So if you frequently use certain files access will be quicker on consequent reads if they are done in a relative short time-frame. Relative because this depends on server load, memory usage etc. Just from the top of my head. But it would still be much slower than caching described.

Robert Koritnik
Neat - its worth noting however that this is not explicitly a caching problem, using generic caching is one solution or at least part of one (and an effective one) but if one did just cache the file there is then the additional overhead of parsing the data. So its more a question of how best to optimise loading of application level data that happens to be stored in a file and may need to be refreshed whilst the application is live.
Murph
That's why I suggested that when you have to load the file it's best to also parse it and store it in object oriented fashion for fast retrieval. This way it will take time to parse just once and use it multi thousand times... Gaining much processing time/power.
Robert Koritnik
Ah, ok - that's not immediately obvious from the opening paragraph (now that you've pointed it out, I can see what you mean)
Murph
Ok I edited my answer so it's more obvious. Thanks for pointing this out.
Robert Koritnik
A: 

There are two ways. Create an Array variable and set it to static.

public class RulesTable
{
    private static readonly RuleCollection _rules;

    public RuleCollection Rules { get; }
}

In this case, you have to create a class like RuleCollection and make it threadsafe.

Or you can use a simple Cache.

System.Web.HttpContext.Current.Cache.Insert("Rules", RulesArray, new System.Web.Caching.CacheDependency("CSV Filename"));
Mehdi Golchin