Software Mechanics
Why do we even have that lever?

Wrapping Async callbacks

June 12, 2009 16:22 by chris

We’ve started adding asynchronous support to the Data Access block. This has been a highly requested feature, so we put it fairly high on our backlog. At first glance, this looked pretty easy. Just add a couple of methods to the SqlDatabase class:

public IAsyncResult BeginExecuteReader(DbCommand command, string commandText, AsyncCallback callback, object state);
public IDataReader EndExecuteReader(IAsyncResult ar);

 

(There are another bazillion overloads, but for this discussion let’s stick to these, ok?)

Starting out

Enterprise Library does a lot of things under the hood. In particular, we have a bunch of optional instrumentation. As such, we want to track things like which command was executed, what the start time was, and a bunch of other stuff. So we decided we needed our own implementation of IAsyncResult. We implemented DaabAsyncResult to wrap around the one returned by ADO.NET, stuffed our extra stuff in there, and read it back out in EndExecuteReader. The two methods started out looking like this:

public IAsyncResult BeginExecuteReader(DbCommand command, string commandText,
    AsyncCallback callback, object state)
{
    IAsyncResult innerResult = ((SqlCommand)command)
	.BeginExecuteReader(callback, state, CommandBehavior.Default);
    return new DaabAsyncResult(innerResult, ... other stuff ...);
}

public IDataReader EndExecuteReader(IAsyncResult ar)
{
    var result = (DaabAsyncResult)ar;
    ... do other stuff ...
    
    return result.InnerResult.EndExecuteReader(result.InnerResult);
}

Pretty straightforward, really. But there are a ton of gotchas here. Let’s take a look at what’s wrong with this code.

Replacing the IAsyncResult object

The first one to pop out is in this line:

var result = (DaabAsyncResult)ar; 

This will end up throwing an InvalidCastException. Why? Because we’re not invoking the callback, ADO.NET is. And it’s not passing our async result object, it’s passing its own, unwrapped one. Obviously we need a way to get our result object in there.

There’s no way that I could find to override how this process works, so we need to cheat a little. The solution I ended up with was to pass, not the original callback, but a small wrapper (using a lambda function) so we can do the switch between the two. This lambda looks something like this:

var wrapperCallback = ar => {
    callback(GetDaabAsyncResult(ar));
}

The obvious next step is, of course to implement GetDaabAsyncResult. This is where things get tricky. Where do we get a hold of the async result? It’s the return value from BeginExecuteReader. When do we have it? After BeginExecuteReader returns, of course. When do we set up the callback? Before calling BeginExecuteReader. Uh oh…

Luckily, C#’s lexical closure features comes to our rescue. What we can do is store the async result in a local variable. Reference it from the lambda, and the value will be captured. So the body of BeginExecuteReader now looks like this:

    DaabAsyncResult result = null; // need null to satisfy definite assignment rules

    var wrapperCallback = ar => {
        callback(result);
    };

    var innerResult = command.BeginExecuteReader(wrapperCallback, state, ...);
    result = new DaabAsyncResult(innerResult, ...);
    return result;

And we’re done! Our user’s callbacks get the right IAsyncResult object, happily wrapped and ready to go. Sadly, not done yet…

Off to the races

Anyone who’s done threading is familiar with race conditions. For those who aren’t, a race condition is a section of code that will produce different results depending on which thread runs in which order. And we’ve got a whopper of a race condition here. Do you see it? I’ll give you a hint – what happens if the wrapper callback runs after BeginExecuteReader returns but before result get assigned?

Yes, it’s a small window, but it’s a statistical guarantee that you’ll hit it every time you’re doing a demo for a huge client or a VC or an Admiral or something (I speak from bitter experience here, trust me). So we need to prevent the wrapper callback from accessing the value of result until we know, beyond a shadow of a doubt, that it’s been set.

Basically, we need one thread to wait for another one to do something. My initial though was to use an Event object. But thinking about that, it didn’t seem right – Events are kernel objects, they need to be disposed, and we may have a lot of these things (one per call to BeginExecuteReader to be precise). Luckily, there’s a lighter weight solution - .NET locks.

We need to introduce a lock so that the wrapper won’t execute until we know that result has been set. Luckily, that’s pretty easy. The code looks like this now:

    DaabAsyncResult result = null;
    var padlock = new object();

    var wrapperCallback = ar => {
        lock(padlock) { }
        callback(result);
    };

    lock(padlock)
    {
        var innerResult = command.BeginExecuteReader(wrapperCallback, state, ...);
        result = new DaabAsyncResult(innerResult, ...);
    }
    return result;

Thanks to padlock, the wrapperCallback might start before result is set, but it won’t continue until that lock is released, and it won’t be until result is safely set. I know the “lock(padlock) { }” line looks a little weird, but it’s legitimate. Calling the callback doesn’t need to be within the lock, and I’ve had many years of “make your lock regions as short as possible” drilled into my brain.

So, there we go, race condition solved. Ship it! Right?

One thing at a time

Unfortunately, there’s another wrinkle in this whole thing. It is allowed for implementers of the async pattern to actually complete the entire operation, synchronously, on the same thread that called BeginExecuteReader, and call the callback before returning the async result. While I have no idea if ADO.NET can actually do that, nothing in the docs says it can’t, and even if it doesn’t now, that doesn’t mean that it won’t in future versions. So we have to handle this case.

This torpedos our design in a couple of ways. First, in synchronous completion, the locks don’t block. Instead it’s just a recursive acquisition of a lock by the same thread multiple times, a completely normal and legal thing to do. In fact, if this wasn’t allowed we’d actually deadlock here, which would be even worse. But this time, since we’re on the same thread, there’s no possible way that the callback can wait until after result has been set.

Luckily, there’s an easy way to tell if this happened – the IAsyncResult.CompletedSynchronously property will be true. We much not invoke the callback until we know result has been set. So let’s do exactly that. In our wrapper, if we completed synchronously we know result hasn’t been set, so we don’t invoke the callback. Instead, we do it manually. And we end up at this:

DaabAsyncResult result = null; 
var padlock = new object();
var wrapperCallback = ar => {
    lock(padlock) { }
    if(!ar.CompletedSynchronously)
    {
        callback(result); 
    }
};

lock(padlock) 
{
    var innerResult = command.BeginExecuteReader(wrapperCallback, state, ...);
    result = new DaabAsyncResult(innerResult, ...);
}

if(result.CompletedSynchronously)
{
    callback(result);
}

return result; 

Wrapping Up

So there you have it. This recipe should work for wrapping any async operation that implements the standard async pattern. It’s a little involved to set up, granted. But the only other approach I could think of was to put my callback on a threadpool thread, thus eating two threads for one async operation. Why do that when one will do?


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories:
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Long overdue – MiniWiki sample updated

June 2, 2009 17:40 by chris

Oy, it’s easy to fall off the blog bandwagon, isn’t it?

I got a request earlier today for my MiniWiki sample, updated to the MVC 1.0 release bits. I went “Sure, I already did that…” and then discovered I hadn’t. Luckily, the RC2 version works right out of the box. :-)

While I was in there I also fixed a minor CSS issue that was mangling my page titles. As usual, it can be downloaded from the download page.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories:
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

Tell me what to work on!

March 27, 2009 06:21 by Chris

We’re about to spin up on development of Entlib 5. As part of that, we want to know what you, yes you want to see in it! Grigori has posted a survey. Apparently, if we did everything it’d take us about 3 years, so we’d like some help from the community to pare it down a little.

Please go take the survey and help me out. And help yourself too, if you’re an entlib user or would like to become one.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: p&p | Entlib
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed

MVC RC2 is here

March 4, 2009 17:59 by chris

The next version, RC2, of ASP.NET MVC framework has been released. With any luck, this’ll be the last one before final release. Great job on the part of the MVC team – I’m really looking forward to this hitting production.

Luckily, I actually got the time to update the Wiki sample before the release this time (even if I’m making the post a little late). head over to the download page to grab it. I took the opportunity to rebuild the sample on top of the latest Visual Studio template, so it doesn’t look quite so ugly anymore. Give it a try, let me know what you think!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories:
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

Updating the Wiki sample to MVC RC1

February 16, 2009 10:10 by Chris

The recently released ASP.NET MVC Release Candidate broke a couple things in my Wiki sample I originally built for MSDN magazine. So, I've updated them again. Major changes:

  • Updated the ModelBinder implementation to match the new semantics
  • Using the global model binder registration instead of the attributes on the action method (although to be honest there's no really good reason for this)
  • No more view codebehind files

At this point, the sample runs, but it's showing it's pedigree as code that's come up from the original CTP's through beta. So after the final release, I'll do one more refresh on this project, and rebuild it from scratch using the final project templates and the latest MVC stuff. I don't expect a whole lot of change in the controllers, and none in the domain model. But the views I expect will change significantly. Hopefully I can grab one of the new themes from the MVC design gallery so folks don't need to keep looking at my ugly lack of CSS skills. ;-)

I've put a permanent home for this sample on my blog at this page: http://www.tavaresstudios.com/Blog/page/ASPNET-MVC-Wiki-Sample.aspx. Go there for download instructions.

Have fun!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | Unity | MVC
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Entlib 5 - and we're off!

January 27, 2009 06:17 by Chris

We're officially kicking off the planning for Enterprise Library 5, and we want your input.

Please head over to Grigori's announcement and give us your opinions on what you want to see.

Basically, what we're looking for is this: you have $100 to put into Enterprise Library 5. It can be spent on bug fixes, new features, documentation, labs, whatever you want, but you can't go over. The more you spend, the more important you think that particular thing is. So, how do you want to spend you $100?

Please either post to Grigori's blog, or here.

Thanks!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | Entlib | p&p
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Resolving a Singleton? Here's how...

January 23, 2009 18:01 by chris

A user posted a question on the Unity Codeplex forum a couple of days ago. He wanted to configure Unity through the configuration file to resolve a singleton object. My first thought was "of course, that's easy". Then I read the actual question and it got a bit more interesting. I thought I'd put my response here instead of the forum because I thought it was an interesting discussion, and I'd like it to still be around the next time it came up.

The thing was, the object in question was an actual singleton, along these lines:

public class MySingleton : IMySingleton { 
    private MySingleton() { }
    public static MySingleton Instance { 
        get { return instance; } 
    } 
    private static MySingleton instance = new MySingleton(); 
} 

He wanted to configure Unity to, essentially, return the Instance property of this singleton class during resolution. That's not so easy.

So, how do you fit something like this into the container? You could write an extension or custom config node to special case it, but that's just asking for trouble. Plus, it encourages use of singletons, which are pretty well understood to be Not A Good Thing these days.

Unfortunately, many times the singleton behavior is forced upon you by libraries or frameworks. Or you may have lots of other code that isn't using a container that you want to leave unchanged. So what do you do?

Luckily in this case, the singleton has an interface on it. So what I'd do is start by creating a new class that has a public constructor, implements the singleton interface, and defers all the methods to the underlying singleton.

public class MySingletonWrapper : IMySingleton {
    public void MyMethod() {
        return MySingleton.Instance.MyMethod(); 
    }
}

Something along those lines.

Next, I'd configure the container to inject the wrapper when asked to resolve IMySingleton. The nice thing about this is that you get simple integration with the code you currently have, and your new classes which you build up through the container are ignorant of both the singleton class and the wrapper; they just use the interface.

You could stop there. That's the nice thing about proper refactoring: at each step you could stop and still leave your system in a working state. But why? Why not get rid of the singleton and let the container manage the object instances? This is pretty easy through more refactorings.

The first thing to do is change the type of the Instance property on the singleton to return the interface type rather than the concrete type. This should be pretty transparent to the callers, and your compiler will tell you if any edits are required.

The next step is to move the guts of the interface implementation out of the MySingletonClass and into the MySingletonWrapper class. Then change the instance the singleton manages to an instance of MySingletonWrapper instead. Finally, change the methods on the interface to delegate to the wrapper instance instead.

public class MySingletonWrapper : IMySingleton
{
    public void MyMethod() {
        DoStuffHere();
    }
}

public class MySingleton : IMySingleton
{
    public IMySingleton Instance {
        get { return instance; }
    }

    private static IMySingleton instance = new MySingletonWrapper();

    // interface implementation now delegates to instance
    public void MyMethod() {
        instance.MyMethod();
    }
}

At this point, all your code should still be running, through the container or not. You should definately change the name of MySingletonWrapper to something a lot more descriptive at this point. That'll be very easy since the only places that use this class name are your container configuration and the MySingleton class.

From here, the next thing I'd probably do is remove the interface implementation from the MySingleton class. This class now has only one responsibility: managing the lifetime of that inner instance.

Now, as you go forward, you should be able to remove references to the explicit singleton and replace them with objects injected from the container. Over time, you should be able to remove all the reference to MySingleton without affecting your code's behavior at all. When the last reference is gone, you delete the singleton class.

And that's how I'd resolve a singleton.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | Agile | Unity
Actions: E-mail | Permalink | Comments (3) | Comment RSSRSS comment feed

Holiday Visitors

January 23, 2009 17:27 by chris

Having just gone through the bloodletting at work (luckily nobody in p&p was on the cut list, but we all know people who were), I wanted to think about something cheerier. And I figured this worked.

My parents came to visit over the holidays. Actually, they almost got stuck here when the airport shut down due to the massive 3 and 1/2 inch snowfall that closed down the Puget Sound area for three days. But that wasn't the cheery part. ;-)

So I'm putting my son to bed, when my father, who was sitting on the couch, hears a tapping on the back door to the deck. Thinking it's the dog, he goes to open the door when he sees the dog asleep on the floor in the living room. So who, pray tell was tapping at the back door?

Visitor

This full size racoon had climbed up onto our back deck, and decided he wanted to come inside. He wasn't aggressive, just cold, apparently. The cat had lots of fun staring at the racoon through the glass door, and we all just sat there amazed. It even tried to scratch its way through the door at one point.

gilbertvscoon letmein

Eventually it wandered off. I've never been that close to a racoon before. I was especially glad it wasn't rabid. :-) I often lament us living out in the middle of nowhere, but sometimes things like this come along to make up for it a little.

Sadly, our pictures didn't come out so well since I was trying to take a shot from a well lit room into a dark area through a glass door, but at least we have some evidence.

Oh, and the dog? Slept through the whole thing. :-)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Personal
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Elegant Code Cast

January 23, 2009 17:01 by Chris

(Whew, I didn't realize I'd gotten so far of the blogging wagon. Time to hop back on!)

At the last Seattle Code Camp, I ended up talking with David Starr for quite a while. He apparently thought I knew what I was talking about (shh! Don't tell him the truth!) and invited me to be a guest on the Elegant Code Cast. It was a great talk about EntLib, life in p&p, Unity, and all sorts of other stuff.

The episode is available here. Thanks again, guys for the great chat!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | Entlib | p&p | Silverlight | Unity
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Announcing Unity 1.2 for Silverlight

December 11, 2008 11:10 by Chris

A little early Christmas present for everyone. ;-)

 

What's in it?

The installer includes the binary, the docs, and a new Silverlight version of our Stoplight quickstart (and no, I didn't port the event broker, anyone want to give it a shot?)

What's different?

Probably the biggest difference is that Microsoft.Practices.Unity.dll for Silverlight is contained in a single assembly. We've merged the previous ObjectBuilder2, Unity, and StaticFactoryExtension into the one DLL. This resulted in a slightly smaller overall package and a lot more convenience when referencing the container, since you don't have to hunt for multiple DLLs when adding references.

One thing that's not included is the XML configuration assembly, Microsoft.Practices.Unity.Configuration.dll. There's a simple reason for that - Silverlight doesn't support System.Configuration. We'll have to come up with a new configuration file story. I'm toying with some XAML based ideas on this front, but it'll be a while.

Also, the recently released interception mechanism (Microsoft.Practices.Unity.Interception.dll) hasn't yet been ported, so that's not included either. We'd like to include it going forward, but it'll take some work to it working and we didn't want to delay the release.

The container basically performs the same in Silverlight as it does on the Desktop CLR. The container API is identical. There is one minor gotcha: due to the difference in security model in Silverlight, you can only resolve public types through the container. The desktop version lets you do public or internal.

How'd we do it?

Luckily, the Silverlight environment really is very close to the Desktop CLR. It was mainly a case of pulling out references to things that Silverlight didn't support. We'd already started down this road with some work done in version 1.2. Replacing calls to methods that didn't exist on Silverlight with ones that did, for example. I did have to tweak a couple of source files (for things we missed) but it didn't affect the overall code any.

In order to do the port, I started by creating an empty Silverlight project. I then imported the Unity source files into it, and then let the compiler tell me what stuff didn't work. Yes, I'm lazy that way.

The vast majority of the code works for both desktop CLR and Silverlight. There were a couple cases where we needed environment-specific code. Looking at the source, you'll see a few files with the .Desktop.cs or .Silverlight.cs extensions. These are how we marked up the code that was specific to one platform or the other. The .Silverlight.cs files are only included in the silverlight project, and the .Desktop ones are specific to the desktop project. For classes that needed to be tweaked, I used partial classes, with the partial parts in a platform-specific file. The various custom exceptions are probably the biggest example of this. On the Desktop CLR, exceptions should have a serialization constructor and be serializable. Silverlight doesn't support this. So each exception class is a partial class. The serialization details are in a .Desktop.cs file. The Silverlight project simply omits those files and we're good.

The unit test suite has also been ported, and uses the same approach. Not every test from the Desktop suite is included, of course. We excluded everything having to do with configuration, for example (which turned out to be rather a lot of tests). Taking advantage of the very nice Silverlight Unit Testing Framework made it pretty easy to reuse our existing VSTS test suite in the Silverlight environment.

What's next?

That's up to you! If you're working on a Silverlight project, please download and let us know what you think! What's important for you? Now's the time, as we're currently prepping for the next version of Enterprise Library and Unity.


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | Silverlight | Unity
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed