Sunday, March 22, 2009

Currying The ASP.NET Cache

I’m reposting this blog entry with code in lieu of images after Ian sent me a rant email quite rightly complaining that he couldn’t read the code in the images (apologies to Ian and anyone else who reads this blog!)

<snip/>

The ASP.NET cache is a thing of beauty. But one thing that fills me with dread whenever I see it is an application littered with ASP.NET caching access code.
One of the other issues that developers have to handle is the possibility that stuff you put in it may not be there next time you ask for it back because the cache is prone to being purged when memory is constrained. This can lead to hideous looking developer code like this:

public void Page_Load(object sender, EventArgs args)
{
        Person p = (Person)Cache["human"];

        if (p == null)
        {
            p = HumanBusinessLogic.GetPerson(Request["id"]);
            Cache["human"] = p;
        }
        // go ahead and use p
}

Yuck!!
To clean up the mess with a little refactoring, we could at least put the cache code in the business logic:

public static Person GetPerson(string id)
{
        Cache cache = HttpContext.Current.Cache;

        Person p = (Person)cache["human"];

        if (p == null)
        {
            p = HumanDataAccess.GetPerson(id);
            cache["human"] = p;
        }

        return p;
}

But the problem now comes that for every business method that uses caching, there will be a cut and paste of the exact same code plus marginal refactor. The solution to that issue might lead us to develop a base class that offers up some kind of caching method that all business logic classes can then derive from and gain benefit.
This base class method would need to solve a couple of scenarios for it to be of any use to a derived class. First, it must look in the cache to see if the item is there and return it if it is. Second, it should have a mechanism of getting the item from the database and repopulating the cache if the item is not in the cache. The first scenario is a breeze, but the second scenario could be problematic. For example, most business logic entities come from a data access method invocation, but how many parameters will the data access method need and what types will they be?


A first crack at solving the problem might be to pretend that the data access method takes no parameters. That way, we could pass a delegate as a parameter that is invoked by the cache code when it detects a cache miss. The code would look like this (and notice the delegate takes no parameters)

public delegate DataTable RetrieveData();

public class CurriedCache
{
    public static DataTable getCachedDataItem(string cacheKey,
                                                        RetrieveData retriever)
    {
        Cache cache = HttpRuntime.Cache;
        DataTable item = (DataTable)cache[cacheKey];
        if (item == null)
        {
            lock (typeof(CurriedCache))
            {
                item = (DataTable)cache[cacheKey];
                if (item == null)
                {
                    item = retriever();
                    cache.Add(cacheKey,
                                item,
                                null,
                                Cache.NoAbsoluteExpiration,
                                Cache.NoSlidingExpiration,
                                CacheItemPriority.Default,
                                null);
                }
            }
        }

        return item;
    }
}

There are some huge issues with this implementation. First of all, it is assumed that the item being stored is a DataTable. Second, there is still the assumption that the retriever function takes no parameters.

To solve the first problem, we can use generics:

public delegate TResult RetrieveData<TResult>();

public class CurriedCache
{
    public static TResult getCachedDataItem<TResult>(
string cacheKey,
RetrieveData<TResult> retriever)
        where TResult : class
    {
        Cache cache = HttpRuntime.Cache;
        TResult item = (TResult)cache[cacheKey];
        if (item == null)
        {
            lock (typeof(CurriedCache))
            {
                item = (TResult)cache[cacheKey];
                if (item == null)
                {
                    item = retriever();
                    cache.Add(cacheKey,
                                item,
                                null,
                                Cache.NoAbsoluteExpiration,
                                Cache.NoSlidingExpiration,
                                CacheItemPriority.Default,
                                null);
                }
            }
        }

        return item;
    }
}

A useful bit of tidy up would be to replace the RetrieveData delegate with the Func<TResult> delegate that Microsoft already define as part of a family of delegates called Func that take no arguments, one argument, two arguments, etc respectively.

namespace System
{
    public delegate TResult Func<TResult>();
    public delegate TResult Func<T, TResult>(T arg);
    public delegate TResult Func<T, TResult>(T arg);
    public delegate TResult Func<T1, T2, TResult>(T1 arg1,
                                                                        T2 arg2);
    public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1,
                                                                    T2 arg2, T3 arg3);
    public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
}

It’s almost done, but not quite. There is still the serious limitation of the retriever function taking no parameters. The solution involves a bit of currying. We will also define overloaded versions of the getCachedDataItem to cater for retriever functions that expect more than one parameter:

public class CurriedCache
{
    public static TResult getCachedDataItem<TResult>(
                                                        string cacheKey,
                                                        object monitor,
                                                        DateTime absoluteExpiration,
                                                        TimeSpan slidingExpiration,
                                                        Func<TResult> retriever)
        where TResult : class
    {
        Cache cache = HttpRuntime.Cache;
        TResult item = (TResult)cache[cacheKey];
        if (item == null)
        {
            lock (monitor)
            {
                item = (TResult)cache[cacheKey];
                if (item == null)
                {
                    item = retriever();
                    cache.Add(cacheKey,
                                item,
                                null,
                                absoluteExpiration,
                                slidingExpiration,
                                CacheItemPriority.Default,
                                null);
                }
            }
        }

        return item;
    }

    public static TResult getCachedDataItem<T1, TResult>(
                                                        string cacheKey,
                                                        object monitor,
                                                        DateTime absoluteExpiration,
                                                        TimeSpan slidingExpiration,
                                                        Func<T1, TResult> retriever,
                                                        T1 a)
        where TResult : class
    {
        return getCachedDataItem<TResult>(cacheKey,
                                            monitor,
                                            absoluteExpiration,
                                            slidingExpiration,
                                            () => { return retriever(a); });
    }

    public static TResult getCachedDataItem<T1, T2, TResult>(
                                                        string cacheKey,
                                                        object monitor,
                                                        DateTime absoluteExpiration,
                                                        TimeSpan slidingExpiration,
                                                        Func<T1, T2, TResult> retriever,
                                                        T1 a,
                                                        T2 b)
        where TResult : class
    {
        return getCachedDataItem<TResult>(cacheKey,
                                            monitor,
                                            absoluteExpiration,
                                            slidingExpiration,
                                            () => { return retriever(a, b); });
    }
}

Notice how the overloaded versions expect the retriever function to be a delegate that takes one or more arguments and notice how this delegate is then invoked in a wrapped delegate of the first type (Func<TResult>)
Since it’s likely we want to be able to lock cached items independently, it probably makes sense to introduce a lock parameter for finer grained locking. The addition of absolute and sliding expiration parameters also give a degree of finer control over caching behavior. The final tidy up also uses lamda expression syntax to invoke the delegates.

Thursday, February 19, 2009

How to actively highlight a GridView row with JQuery

In a project, recently, I wanted to switch over to using the CSS Friendly Control Adapters to get the GridView to render its TR’s and TD’s with a CSS class so that all the styling could be dropped into a style sheet. The reason for doing this was because we wanted to highlight the row underneath the mouse by leveraging JQuery magic, thus improving the end user experience when there are many rows (See image below)



The problem with the CSS Friendly Control Adapters is the all or nothing behaviour. Once you activate them in your project, they have global effect. I went looking for a mechanism that would allow me to turn off the effect on a per GridView basis and was initially excited to see the GridView attribute AdapterEnabled="false"...but after a short test, it became apparent that it doesn’t work!

So, I decided to dump the CSS Friendly Control Adapters and go for a home grown route instead.

The first thing to do is to *remove* <RowStyle> and <AlternatingRowStyle> elements in the GridView and add a CssClass=”selectableGridView” (see image below):



If you fail to remove these elements, they produce HTML as seen below (see how the element gets translated into a style='....' in the HTML)

....and don't forget to add the CssClass=”selectableGridView” to the GridView (as marked in the green square)



The reason for removing them is because we’re going to be using JQuery to add a class dynamically to the row when the mouse is over it and this will have no effect whatsoever if the local styling is left in place. By the way, there's another bonus for doing this and that's to reduce the size of the page which will therefore increase page load time.

So, the JQuery code looks like this:




The JQuery code has two jobs it must do. First, it needs to put back the row style and alternating row style. This is done with the following code:

$('.selectableGridView tr:odd').not(':has(th)').addClass('SelectableGridViewAlternateRow');

$('.selectableGridView tr:even').not(':has(th)').addClass('SelectableGridViewRow');

The first line applies the alternating row style via the class .SelectableGridViewAlternateRow and the second line applies the normal non alternating row style via the class .SelectableGridViewRow. We need to be careful not to include the rows that are in the table header, hence the .not(':has(th)') selector to filter those guys out.

The next piece of JQuery magic is to highlight the row underneath the mouse.

$('.selectableGridView tr').not(':has(th)').mouseover(function() {

$(this).addClass('SelectableGridViewHighlightRow');}).mouseout(function()
$(this).removeClass('SelectableGridViewHighlightRow');});

Again, we simply filter out the rows in the header and then apply the .SelectableGridViewHighlightRow class in mouseover and then remove it in mouseout.

To finish up, the style sheet sets up the rules needed to bring it all together

Sunday, December 28, 2008

understanding C#'s yield return statement

The C# yield return statement causes the C# compiler to generate a fair amount of additional IL instructions. This generated code can easily be seen with a tool like Reflector. Although, understanding exactly how the generated code works is not especially easy from first glance since it is rather verbose and somewhat lacking in useful variable names.

A first port of call might be to extract the generated code with Reflector into a Visual Studio .NET C# source file. Sadly, an attempt at compilation will result in errors :( It turns out that the generated IL code does some things that ordinary C# programs are forbidden to do.

Specifically, the iterator syntax magic creates an implementation of IEnumerator.MoveNext() that can be called multiple times, with each call returning to the same point it was at previously, prior to returning last time round. So how does it do that? How can you call a method multiple times and each time have it resume from the exact same point it left previously?

To see this programming style in action, one approach might be to write a simple program from scratch that demonstrates how you could mimic the behaviour of calling a method multiple times and returning to the same point you previously left off. C# is not going to be the right language choice since it forbids the very programming style we want to emulate! It turns out that a simple C++ program is a good candidate for demonstrating the concept and has the benefits of being compilable and therefore debuggable and also reasonably easy to understand.

As an example, consider the following C++ program that displays the first 6 prime numbers with a function GetPrime() that when called each time will return the next prime number in the array.




For simplicity, the program uses several global variables but it’s not hard to imagine these being hoisted into a class as member variables with the GetPrime() function elevated to method status.

The program begins life by calling GetPrime() for the first time. At this time, the global variable called ‘state’ has a value of zero, so the code enters the while loop and extracts the first prime number from the array and sets the global variable ‘state’ to 2 before returning the prime number from the function. The next call into GetPrime(), we note that ‘state’ has a value of 2, so it will trigger the case that causes the code to jump back into the middle of the while loop (effectively jumping back to the exact position where it left last time had it not returned from the function) with goto getAnotherPrime and so the code loops round to extract the next prime number from the array and returns it to the caller. When the global variable ‘count’ is no longer less that the number of primes in the array, the while loop in GetPrime() will drop out and cause the function to return zero, thus causing the while loop in _tmain() to terminate.

The naughty part of the code from a C# perspective is the goto label (getAnotherPrime) appearing after a return statement, something the C# compiler considers to be unreachable code (which seems quite reasonable).

So the secret of the technique is to maintain a state machine in memory of where the code is at in the loop. If ‘state’ is 2, then it means the next call to GetPrime() should re-enter the loop at the place it last left off (that place being just after the return statement). If 'state' is 0, then this is the very first call into the function and iteration is commencing. When 'state' has the value 1, it doesn't stay that way for long since the code will loop back round and soon become 2 again. The assignment of value 1 into 'state' doesn't have much effect other than keeping the compiler happy such that the label actually serves a purpose.

If you understand the above code then it should now be reasonably trivial for the reader to decompile the following C# program with Reflector and see how it uses this exact same state machine technique in IEnumerator.MoveNext():

Sunday, November 02, 2008

Cloud Computing

I did not attend PDC this year so I'm blogging on the back of having streamed the Ray Ozzie keynote.

I feel sure I won't be the only person to wonder whether Cloud computing is likely to be a huge success for Microsoft. In theory, it makes a lot of sense, but in practice, I can't help wondering whether this is to a large extent another 'Hailstorm'-esque Microsoft dream. Will companies really be queuing up to have Microsoft data centres host their application code and corporate data? However wonderful the platform may turn out to be, what does it mean to pass responsibility for the safe keeping of your data with a third party like Microsoft?

Why do we need Cloud computing anyway? What does it do such that we cannot live without it? I mean, if we look at .NET and ask the same question, the answer seems obvious - we could not live without it and thank goodness the COM era came to an end. Anyone who uses a computer in the modern world reaps benefit from the technological innovation of .NET - will the same be true of a Microsoft cloud?

Well, I guess the cloud could provide unlimited scalability with that kind of horsepower packed into the huge data centre. But I wonder how many companies will actually need that kind of scalability? And doesn't scalability really boil down to writing code that can be scaled in the first place as opposed to taking any old bit of code and throwing more cores at it? I'm thinking of plentyoffish.com when I say this - one smart guy (Markus Frind), 2 databases, one web server and thousands of hits per day with a truly scalable piece of software. I'm pretty sure he doesn't need the cloud and I'm pretty sure he gets more hits than most companies who will sign up for the cloud.

Failover also has to be a consideration in any scalable application, but do we not already have web server farms and SQL Server clusters that keep the ecosphere of Microsoft applications more than available?

To a large extent, I think it's going to boil down to price. If Microsoft can host your code and data in their cloud at a significantly reduced cost to your business than you hosting it, then perhaps they're onto a winner. But even if they do manage to make the cloud financially competitive, the question still remains as to whether you trust Microsoft to be the caretakers of your company's greatest assets.

Friday, May 30, 2008

JSONized query strings

I often have to Response.Redirect to an ASP.NET page that takes a lot of parameters. There are a few ways of doing this. One way might be to invoke the page with a query string that contains the parameters:
Foo.aspx?a=66&b=77

If you think of the query string parameters as bunch of properties on a class then you could easily see how one might author that class to also serialize and deserialize the query string by leveraging StringBuilder.Append or String.Format and String.Split etc etc.

I’ve been working with Microsoft AJAX recently and I'd used the text based JSON serializer a couple of times and it got me thinking about how I might leverage that to serialize my object properties to and from the query string. [The XmlSerializer might seem like another approach, but ASP.NET really doesn’t like angle brackets (even encoded) sent as data in the query string – it barfs in case you were wondering with a ‘that data looks very suspicious’ type message.]

So I decided to give the JSON parser a whirl and it works like a charm. Here’s what my JSON encoded query string looks like:

Foo.aspx?qps={"A":66,"B":77}

Here's the class:


Here's the caller:


Here's the callee:


I *always* wrap the FromJSON call in a try / catch block in case someone tries to send a hacked query string that clearly won’t deserialize.

Monday, May 05, 2008

Creating 'Expression Blend' ScrollBars in WPF

The scroll bars in Expression Blend are very nice. Nice enough that I thought I’d spend some time this afternoon figuring out how I could modify the WPF scroll bar control template. Fortunately, it turned out that there really wasn’t that much work involved. Here’s the result:



I started off by grabbing the template from
MSDN. The scroll bar template consists of a style that brings into play either the VerticalScrollBar template or the HorizontalScrollBar template via the Orientation dependency property as seen:



The remaining discussion will only focus on the VerticalScrollBar, since the solution is almost exactly the same for HorizontalScrollBar.

The RepeatButton defined in the VerticalScrollBar template seen at Grid="0" and again at Grid="2" defines the up arrow and down arrow respectively. I made these a little more elongated to mirror the Blend arrows by changing the content properties as follows:

Top arrow: Content="M 0 8 L 8 8 L 4 0 Z"
Bottom arrow: Content="M 0 0 L 4 8 L 8 0 Z"



The scroll thumb also needed some attention. The shape of the thumb at both ends is more rounded than the default, so I increased the CornerRadius:
CornerRadius="4"

Also, the thumb in blend has no border, so I removed the BorderBrush and set the:

BorderThickness="0"

Another difference is that the thumb is highlighted when the mouse is over it and changes colour to black while it is being dragged. Both of these are dependency properties that can be modified to the appropriate values with triggers:




Notice that I had to give the Border a name ‘roundedBorder’ so that the triggers could reference it.

ScrollBarLineButton defines the style and template for the repeater button that houses the arrows (which will end up being up or down for vertical scroll bar. And left or right for a horizontal scroll bar). The template for ScrollBarLineButton acquires the visual for the arrow by databinding to the Content property of the template parent – a neat trick that means only one ScrollBarLineButton needs to be defined for the whole template to be able to deal with all four arrows.


To get the ScrollBarLineButton to look like the blend version, I had to make a few more changes. The arrow is highlighted when the mouse is over it – in much the same way as the thumb. To achieve this, I gave the Path a name ‘glyph’ and then changed the trigger ‘IsMouseOver’ to retarget to ‘glyph’ Fill to the colour: GlyphMouseOver. The IsPressed trigger also needs to mirror the thumb and sets the ‘glyph’ Fill to black.



Finally, I also had to change some of the brushes defined for the scrollbar. Here are the changed versions:
<SolidColorBrush x:Key="GlyphBrush"Color="#FF7E7C7C" />
<SolidColorBrush x:Key="GlyphMouseOver"Color="#FFE8E8E8"/>
<SolidColorBrush x:Key="PressedBrush" Color="Black"/>
<SolidColorBrush x:Key="NormalBrush"Color="#585858"/>

Thursday, January 31, 2008

WPF CoverFlow Clone

I recently decided to spend some time hacking up a CoverFlow clone in WPF. Of course, what I managed to achieve in the space of a day is nowhere near as good as the real CoverFlow application that Apple deploys but that's not the point! The point is, it amazes me how quickly and effortlessly I was able to do it with the power of WPF. It also amazes me how long something similar would have taken in any previous technology like Windows Forms or Win32!

Here's what the 'final' XBAP version looks like:




My approach was to almost completely restyle a ListBox. The first step was to redefine the ControlTemplate of ListBoxItem to be a Grid of 1 row and 1 column containing a StackPanel which in turn contained both the ContentPresenter and a Rectangle. The rectangle is there to produce the reflected image of the ContentPresenter.

Here's the XAML for doing that:





The VisualBrush used to paint the Rectangle has to be flipped in the Y-axis with a ScaleTransform and then put back into the correct position with the TranslateTransform. The TranslateTransform figures out how much to offset in the Y axis via databinding to the ActualHeight of the ContentPresenter. The OpacityMask applied to the Rectangle ensures that the reflection gradually dissolves away.




The StackPanel that contains the ContentPresenter and Rectangle (reflected image) looks like this:





This has a couple of transforms that do nothing until they are animated later; a TranslateTransform and a ScaleTransform.



When the ListBoxItem is selected, several animations run in parallel, effectively moving the StackPanel down in the Y axis by running the TranslateTransform while at the same time running a ScaleTransform which enlarges it in X and Y. The combined effect of these animations running in parallel is the sensation that the selected ListBoxItem springs forward towards the end user.



The animations are initiated by EventTrigger's; one each for the routed events: ListBoxItem.Selected and ListBoxItem.Unselected. Here's the XAML for the animations in their respective EventTrigger's





When the ListBoxItem becomes Unselected, the Unselected EventTrigger ensures the StackPanel moves back into it's original position and size prior to being selected - effectively reversing the work done of the Selected EventTrigger.