May 2011 - Posts

CacheAdapter–Now a Nuget package
Tuesday, May 31, 2011 5:12 PM

Note: Link to Wiki is here

A while ago, I blogged about a personal project around caching that allowed you to abstract away the underlying cache mechanism, and use whatever cache you wanted. Through simple configuration, you can choose to use either the memory cache provided by System.Runtime.Caching in .Net 4, the traditional ASP.NET web cache, or you can use the Windows AppFabric caching to taker advantage of distributed caching.

Well, its now a package on Nuget that you can easily install and use immediately. You can grab it from here.

install-package-image

Update: This package uses the Microsoft Public Licence (MS-PL).

Just as a recap, you can use this cache adapter like this:

var data1 = cacheProvider.Get<SomeData>("cache-key", DateTime.Now.AddSeconds(3), () =>
{
    // This is the anonymous function which gets called if the data is not in the cache.
    // This method is executed and whatever is returned, is added to the cache with the
    // passed in expiry time.
    Console.WriteLine("... => Adding data to the cache... 1st call");
    var someData = new SomeData() { SomeText = "cache example1", SomeNumber = 1 };
    return someData;
});

(Note: You will get a small example .cs file included in your project that contains this example usage when you install the package)

You can see in the example, that you can request the data, and provide a lambda that retrieves that data if its not in the cache. The data gets added to the cache once the lambda has been executed to retrieve the data from the source. Also, the data that is returned is strongly typed. It is not a generic object that you then need to cast.

Additionally, you can set the type of cache used by one line of configuration:

<setting name="CacheToUse" serializeAs="String">
    <value>Memory</value>
</setting>

If I wanted to use the ASP.NET Web cache, I could simply set the config item like so:

<setting name="CacheToUse" serializeAs="String">
    <value>Web</value>
</setting>

And if I wanted to use the AppFabric distributed cache (assuming it has been installed on the system), then I can simply set the config like so:

<setting name="CacheToUse" serializeAs="String">
    <value>AppFabric</value>
</setting>

The package references the required AppFabric client assemblies for you. This means you can write a web application today using this package and use the traditional ASP.NET cache. Then we you are ready, install AppFabric, setup a cache cluster, change the configuration to enable AppFabric and you are away. No code changes to your app.

Using AppFabric

To use AppFabric, there are a few extra things to do by way of Infrastructure. Obviously, you need to download and install it. Then you need to setup your cache cluster via the wizard when you install it (or via powershell if you choose). During this process you will be creating some cache nodes and you need to create a named cache for your application. This can be done via powershell using the

  • New-Cache {cachename}

powershell command. In addition, you will need to ensure that the user that will be accessing the cache has access to it. Again, this can be done from powershell via the:

  • Grant-CacheAllowedClientAccount {account}

There is some additional config you will need to do as well. In the application config file you will need to change the following entries to match your configured infrastructure:

<setting name="DistributedCacheServers" serializeAs="String">
    <value>localhost:22223</value>
</setting>
<setting name="DistributedCacheName" serializeAs="String">
    <value>MyCache</value>
</setting>

The “DistributedCacheServers” setting can be a comma separated list of servers and ports that the cache client (ie. your app) will communicate with. This can be one or as many comma separated entries as you like and depends on your cache cluster config.

The “DistributedCacheName” is the name of the cache you have setup in the cache cluster for your app. (Detailed above)

Final Notes

Before I published this package, I cleaned it up a bit as I have been using it on a current project and I didn’t like a number of ways I implemented things initially. Instead of multiple assemblies, everything is in the one assembly.

Also, I removed the use of Unity as a mechanism for dependency injection and implemented a very very simple method which uses no particular dependency injection implementation. I did this because everyone wants to do DI (Dependency Injection) using their favourite implementation whether this be Unity, Autofac, Ninject, Castle Windsor etc. etc. So I opted for something that does the job, it is not what a purist would be happy with, but is dead simple to rip out and change which is what I expect most people would do.

Finally, because all cache access is via an interface, it allows for easy testability.

So go grab it. Or you can download the source code form here and change it to your hearts content. Its actually a relatively simple implementation and it would be easy to plug in any underlying cache implementation should you wish.

Diskeeper–a short review
Monday, May 16, 2011 9:23 AM

I have been lucky enough to be ASP.NET MVP for a number of years now. One of the perks of that is you get access to free licences of software such as Diskeeper. This piece of software keeps your disks running as smooth as they possibly can.

I have been using Diskeeper for around 2 months now and am pretty impressed. It silently does its thing in the background without you having to touch anything. One of the newest and also one of my favourite features is the automatic defrag capability.You don’t have to launch a defrag application and have it run on your system or schedule it to run periodically, as Diskeeper performs this operation all the time, in the background for all disk operations. Basically, you just use your system like normal, and it just magically gets defragmented, all the time. Nice.

I have 2 disks in my system. A SSD (Solid State Drive) as my primary ( C: ) drive, and a 5200rpm 320Gb hard disk as my secondary data drive ( D: ). After installing Diskeeper, I have noticed a significant difference in the performance of the secondary drive in particular. I imagine because it is the slowest disk and because it stands to benefit the most. The SSD is fast anyway, so it is much harder to notice any difference. I have noticed a small difference, but it’s only slight compared to the secondary ( spinning rust ) drive.

I should mention that in order for Diskeeper to work with SSD hardware, you need a special edition of Diskeeper with an add-on called Hyper-fast that takes into account the SSD unit and has special algorithms that are designed to optimise SSD operation.

For those interested in the actual metrics, Diskeeper provides an easy to use management console that displays your current system improvements. The initial display is shown below.

image

The management console offers a number of ways to look at what has been done to your disks and how it has been performing. I find the history view particularly interesting as it proves a look at how the disk is being used and optimised over time.

image

So would I recommend it? Yes, and this is not simply because I have been given a free licence and feel obligated to do so. It is particularly useful if you have standard hard disks regardless of how fast they spin. You will notice a much smoother and responsive system as a result. For SSD owners, it is still worthwhile but the benefits are less because of the inherent speed in SSD units. For a system with a mix of SSD and hard disks, it works beautifully.

Entity Framework and the PreApplicationStartMethod attribute
Friday, May 6, 2011 2:09 PM

Recently, while implementing an EntityFramework data model into a new application, I thought I’d add some caching functionality early, to establish a framework going forward. I added the DBML (generated from a database), and added in my funky caching layer (which will be distributed as a Nuget package soon) that allows caching to be configurable switching between in memory, ASP.NET cache and AppFabric caching.

Anyway, I added some repository methods to grab data from the database. All good. I added my caching layer to that so that a bunch of reference data was cached, again all good.

Now this application is a .NET 4/ASP.NET MVC 3 application and I was using the PreApplicationStartMethod attribute to specify a class method that is executed before anything else in the application. Something like this:-

In the AssemblyInfo.cs file I had this attribute declaration:

[assembly: PreApplicationStartMethod(typeof(WebAppStart), "PreStartInitialise")]

And in the WebAppStart.cs file I had this:

public static class WebAppStart
{
    public static void PreStartInitialise()
    {
        RegisterWebDependencies();
    }
}

This all worked well. Then I thought, well rather than let the first user of the application cause the cache to get primed/filled, I would simply make a call to a method I had already to prefill the cache:

public static void PreStartInitialise()
{
    RegisterWebDependencies();
    PrimeCache();
}

Seems ok so far, but alas no. Apparently, you cannot use the EntityFramework from within a method invoked by the PreApplicationStartMethod attribute. What you will get is an exception message like this:

RealExceptionMsg

The solution was easy enough for me, I just moved the PrimeCache method to the Application_Start event within the Global.asax.cs file. However, what made this error, let’s say “interesting” is that I was developing an azure application. What then happens is you get an error that seemingly has nothing to do with the root cause. So when developing running in debug mode for an azure application you get the following exception:

 

ExceptionOnRunningApp

It seems to point to some issue with the connection string which is absolute rubbish and leads you to nowhere. If you happen to try and run this without attaching a debugger, then you simply get an exception dialog stating that the windows azure web role has stopped working.

ExceptionMsg 

Nice.

So, the moral to this story. Don’t use EntityFramework within a method defined using the PreApplicationStartMethod attribute. If developing an azure app and you get this error, do not believe what you are told. Move the EntityFramework code to somewhere later in the lifecycle and you will be good.

More Posts

This Blog

Syndication