Aaron Murrell

Aaron's blog - a few choice words.

9/24/2007 9:15 AM (UTC+05:30)
by aaron

Mother and baby, both wonderful - as perfectly formed as could possibly be imagined.  What an amazing and awe inspiring journey the past 36 hours has been!

 

DSCF0840

born 09/23/2007 11:17 am CST (Houston, TX)

0.003715625 short tons

0.000315656566 miles long

light years beyond what I could have ever imagined.

9/12/2007 9:01 PM (UTC+05:30)
by aaron

Let me start by saying that I work for a company who is a HUGE Microsoft partner.  I live and work in Visual Studio, Outlook, Office, Project, SQL Server... you name it and have recently even found myself highlighting the merits of Windows to a few co-workers who have started taking on a Mac-loving isolationist attitude.  I'm not bashful about stating that Microsoft products have been my bread and butter for a long time.  But I'm finding it really difficult to contain my underwhelmedness (is that a word?) on the Groove 2007 release.

In an effort to get our project proposal teams to work more fluidly together I recently found myself championing Groove 2007 in front of the IT management of our company.  This is after having worked with Groove (a version previous to 2007) at a client company and being pretty pleased with what it added to the dynamic of group collaboration.  After installing the 2007 version this week I have to say that I am sorely disappointed in what Groove offers in its current feature set.  Honestly, it should be considered a beta in its current state.  I'm not even sure how it earned the "Office" badge (it is currently bundled in as a Microsoft Office product) considering its lack of integration with Office 2007 in general.

After reading this FAQ on Microsoft's website it was evident that some key features just didn't make it in to this release.  I refer to it as the Groove apologetics document.

Here's what I was looking forward to seeing in Groove 2007 that is totally MIA:

  • More integration with Sharepoint 2007.  I can have a Groove "files" tool synchronize with a Sharepoint document library and this is great, but where is:
    • Calendar synchronization with Sharepoint?
    • Task list synchronization (actually Groove 2007 doesn't even have a task list at all!)?
    • Synchronization of files with my local file system (i have to open a document from Groove for it to detect changes)
  • Integration with Office 2007:
    • The only detectable integration with MS Office that I could find was that it spawned a new email message to invite a new user to a workspace when asked.  C'mon guys, really...
    • Outlook should aggregate workspace calendars to provide a comprehensive view in my Outlook calendar.
  • Project planning:
    • Honestly when I first saw this feature in the previous version of Groove, I couldn't imagine using it.  But when I installed it this week I was actually looking forward to using its capabilities for organizing tiger teams to write responses to RFP's, collaborating to write SOW's and Proposals and the like.  The FAQ document above seems to be positioning the calendar tool as a replacement for the project planner.  Nope, I'm not buying it - it just won't work like that.  I can't even approximate the value that a Gantt chart brings to project planning with a simple calendar.  At least integrate MSProject into the mix.

Bottom line:  Fine, you couldn't get the good stuff in this release.  I'm ok with that.  Just don't position it as though you did, and you might as well reduce the price on this version to be commensurate with the value it brings to business.  (Say... ummm... $50 sounds about right).

8/28/2007 11:09 PM (UTC+05:30)
by aaron

It was about a week ago when the patient presented with a problem.  "Dr". he said:  "my WCF service hurts really badly lately - especially when I do this".  He lifted his service up to show me.  "Ouuuch."

"Hmm" I replied, "has your service been properly adhering to the tenets of SOA and washing behind his endpoints regularly?  It's important for growth you know." 

"Well," the patient sulked a little... "its bindings endpoints and are spanky clean.  They're practically brand new, but I have to confess that I haven't been paying much attention to the tenets of SOA.  I know all about them, explicitness, autonomy, schema and contract over class implementation, policy rules yada yada yada.  But I really didn't care about all that when I started.  And honestly I still don't."  I gasped. 

Seeing me react, the patient became more determined to finish and talked faster and louder.  "Those things just didn't seem important in my case.  Honestly, I really don't think they apply to me.  I don't plan on showing other people my services.  I'm not into that kind of thing.  I know other people are, but I only care about being able to cross process boundaries."  With my forehead wrinkled I crossed my arms ready with a barrage of questions. 

"I though you were building a web application." 

"I am" he said. 

"Then why do you need to cross process boundaries?"  I was puzzled. 

"Well, you see, sometimes the web app will be deployed in a DMZ where firewall ports have been opened to connect to a database, and sometimes the web app will be deployed in an environment where only port 80 is open." 

I grimmaced and thought to myself.  There's a bigger disease here.  "Well," I said "requirements are requirements".  The patient continued: 

"I am using ActiveRecord for this project in conjunction with code generation.  I'm generating all of my classes with this in mind.  I'd like to set the architecture up so that the user interface uses a factory of sorts to either give me references to my persistent objects in process or give me references to service proxies based on some application configuration settings.  Of course I would always handle the object references via their corresponding interfaces so the user interface code isn't concerned with the implementation details of whether it has a reference to a service proxy or a real in-process object from my domain model.  The plan is to create a service for each persistent object, you know, mark up each persistent class with ServiceContract attributes.  The trouble is, that when I generate my WCF service proxies based on my persistent objects they look really ugly.  Not only are they ugly, but the persistent objects combine state as well as behavior, and without the state, the behavior doesn't work.  Some members do calculations depending on the state of other members.  Then of course there's the CRUD (Save Update Delete etc) members.  I know its frowned upon, but I'm strongly considering making DTO classes strictly to use as data contracts to pass to the CRUD members."  "Man, just talking about it makes my service hurt again!"

"Allright," I said.  I think I see what's going on.  "The problem is that you're an object biggot."  "I thought that was a good thing!" he cried out. "Well, normally I think it is, admittedly I am too, but, now that you've got a service involved, things are different.  You're trying to treat your objects as services and what you've got to accept is that they're just not the same.  Unfortunately that will always be painful."  I got out my prescription pad and quickly scribbled down my recommendation.  I handed my patient the small square piece of paper.  Excitedly he examined it to see what the remedy was.  "That should get you where you want" I said confidently. 

"Remoting!" he exclaimed.  "Oh no.." he shook his head looking down at the floor.  "That just won't do."  "What you don't know, Dr., is that I've alredy asked several people. I've already talked to three other doctors and ALL of them said 'never under any circumstances ever ever use Remoting." 

I didn't say it out loud but I thought to myself "aha, he's been seeing those WCF biggot quacks." 

"Listen," I said, "they want you to use WCF because they want you to use real bonafide services.  They want your services to grow up to be strong and healthy SOA tenet adherent services.  All of that is fine, but you're an object biggot, you don't really want to use services and you probably never will.  You'll never change.  Trust me, you want remote objects.  if you take the perscription I gave you, you can use your objects remotely, across process boundaries the same way you would use them in process.  Depending on your performance requirements, I think it should work out just fine, and your UI layer will never know the difference.  In the morning the pain will be gone and you'll feel right as rain.  Although, you might wonder why you didn't come talk to me sooner."

There was a long pause.  I could tell he was thinking.

"Unless..." I said.  "you're willing to go through a little surgery." 

"Using our new surgical refactoring tools, if we can identify only the functionality that requires us to cross process boundaries, we can cut those service concerns away from the rest of the behavioral concerns that you have in your objects.  We would leave your objects mostly intact, move the factory along with your service layer behind a dynamic proxy implant, defer the delegation of only persistence calls to the dynamic proxy implementation class and based on configuration either do a service lookup or simply delegate calls to our in process object."

I paused. The patient looked a little green in the gills.  "I think I'm going to need to see this on a whiteboard" he said.

"Ok, let's draw this out" I said, and grabbed a marker

We'll take a class like Person as an example:

"What are the responsibilities that simply must be executed on the service side of your application?" I asked.

"The persistence stuff". He replied.

"Excellent. We'll move only the persistence stuff inside of our WCF service, creating a service class for each persistent object.  We'll end up with a PersonPersistenceService, a DogPersistenceService, a TruckPersistenceService etc.  You get the idea.  Using your code generation, this shouldn't be a big deal.  These will be the services we expose through endpoints."

"Since we don't want to generate or write or maintain that logic twice, when we create our Person class, we'll inherit from PersonPersistenceService."  Our Person class will also implement the IPerson interface that we created so that we can substitute a dynamic proxy for an actual Person object when the factory is used to get a Person object.  The IPerson interface extends another custom interface called IPersistable.  It has generic Save, Update, Delete, and Load methods that are implemented by using our PersonPersistenceService methods.  Our Load method will use the Specification pattern (a close cousin of the Command pattern) taking in a specification (we'll call it a QuerySpecification) of what we expect to load.  This way we have a generic representation for loading sets of objects no matter what type they are or what the query represents.  Finally, our Factory class will use the Cramon.DynamicProxy library to substitute a dynamic proxy for a real object.  All method invokations on our proxy will flow to a custom DynamicPersister class which contains the logic to either route method calls to the object being proxied, or to a corresponding WCF service that persists Person objects.  By the way, our Person object is marked up with DataContract attributes to selectively cull out state information.  It would be nice if we could have marked up our IPerson interface instead but WCF requires data contracts to be codified as concrete classes."

The drawing looked something like this when I finished talking:

image

"Ahh I see," he said.

"So, are you ready to go under the knife?" I asked. 

to be continued...

(note: I do not suppose myself to be an actual Doctor of WCF.) 

8/14/2007 7:11 PM (UTC+05:30)
by aaron

There's not much that's more frustrating than taking the time early on in development to work out your unit tests only to discover later during integration that what worked beautifully in NUnit and VSTS tests doesn't actually work in the context of the larger system.  I don't think I need to spell out what's coming next.  Yup... I'm a victim.

First, the morals of the story:  Don't let WCF synchronization context bite you in the ass; and there's no substitute for a good book and subsequently the knowledge you can put in your head using the right book.

Ok, here's the scenario that you never want to find yourself in:

Ingredients:

  • One console app WCF host (substitute WAS host or Windows Service host if desired)
  • One windows forms app client
  • One WCF service with a callback

here's the layout:

 

image

Inside the Winforms client I get a reference to my service proxy and pass in an instance of a class that implements the service's callback contract (which happens to be the form itself) ... no big deal.  It looks something like this:

public partial class Form1 : Form, ICalculatorServiceCallback
{
    ICalculatorService proxy;
    public Form1()
    {
        InitializeComponent();
        System.ServiceModel.Channels.Binding binding = 
            new NetTcpBinding(SecurityMode.Message, true);
        EndpointAddress address = 
            new EndpointAddress(@"net.tcp://localhost:4000/CalculatorService");


        InstanceContext context = new InstanceContext(this);
        DuplexChannelFactory<ICalculatorService> factory = 
            new DuplexChannelFactory<ICalculatorService>
            (context, binding, address);
        proxy = factory.CreateChannel();
    }       

    private void Form1_Load(object sender, EventArgs e)
    {

    }

Here is the implementation of the callback contract further on down in the form:

 

        #region ICalculatorServiceCallback Members

        public void AddInvoked()
        {
            System.Diagnostics.Debug.WriteLine("Yo!");
        }

        #endregion
 

Finally, a button clicked routine (also defined in the form) to actually use the proxy:

        private void button1_Click(object sender, EventArgs e)
        {       
            proxy.Add(23, 44);
        }
 

As for the service side, the host is a pretty typical console type host that again imperatively sets up a singleton instance of the CalculatorService which implements the ICalculatorServiceContract:

class Program
    {
        static void Main(string[] args)
        {
            ICalculatorService singletonCalculator = 
                new CalculatorService();
            
            ServiceHost calculatorHost = 
                new ServiceHost(singletonCalculator);

            NetTcpBinding binding = 
                new NetTcpBinding(SecurityMode.Message, true);
            Uri address = 
                new Uri(@"net.tcp://localhost:4000/CalculatorService");

            calculatorHost.AddServiceEndpoint(
                typeof(ICalculatorService), binding, address);

            calculatorHost.Open();
            Console.WriteLine(calculatorHost.State);
            Console.WriteLine
                ("CalculatorService started, press any ENTER to close...");

            Console.ReadLine();
            calculatorHost.Close();
        }
    }

The service looks pretty much like you would expect.  The important part of the actual service is that it is decorated with a ServiceBehavior attribute indicating that the InstanceContextMode shoudl be set to single, thus making our service a singleton.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculatorService
{

    #region ICalculatorService Members
    private Dictionary<string, float> memory = 
        new Dictionary<string, float>();

    public void Add(params float[] nums)
    {            
        Console.WriteLine("The Add Method was invoked by {0}", 
            System.Threading.Thread.CurrentPrincipal.Identity.Name);
        DoCallback(nums);
    }

    private void DoCallback(float[] nums)
    {
        ICalculatorServiceCallback callback = 
            OperationContext.Current.GetCallbackChannel
            <ICalculatorServiceCallback>();
        callback.AddInvoked();
    }

So far nothing interesting right?  In fact I don't even think there's even any adding logic in there.  Oops.  Ok, here is where things start to get a little wiley.  The symptom I was seeing was manifesting itself in the Winforms client.  The CalculatorService Add() method would get called appropriately in the button event, but then the Winforms app would unexpectedly freeze.  Eventually I'd see a timeout error from the client's proxy and then the callback would fire.  Weird.  Connectivity issues were hard to prove because the service call was being serviced, and the callback would eventually find its way to the client callback method.  The more I looked the more it became painfully obvious that I had a threading deadlock issue.  Keep in mind that this all worked in my 'integration' unit tests that did the hosting and the client calls in the same process.  Then I remembered reading about concurrency modes and it seemed to make sense that the default ConcurrencyMode setting on the service might be the problem.

In a nutshell, you can instruct WCF to dispatch simultaneous incoming calls to your service in several different ways with respect to threads.  This is done using the ConcurrencyMode attribute on your service.  The default mode is ConcurrencyMode.Single.

ConcurrencyMode.Single tells WCF to lock concurrent access to the service down to one thread at a time.  Incoming calls are queued up and dispatched in order.  Any call that waits in the queue longer than the service's timeout will throw a timeout error on the client. 

ConcurrencyMode.Multiple and ConcurrencyMode.Reentrant are also available. 

The advantage of using ConcurrencyMode.Single (and I'm sure this is why it was chosen as the default value) is that it is threadsafe by nature.  As a service developer, you don't have to worry about locking concurrent access to service state inside service logic because the entire service is locked down by WCF.  If you want to handle things manually you can choose ConcurrencyMode.Multiple.  ConcurrencyMode.Reentrant is a unique beast and we'll come to that in a moment. 

Now, if you plan to callback to your client(s) during the actual execution of a service operation, having the default mode of ConcurrentMode.Single just won't do.  WCF will attempt to dispatch the callback, find that the resources it is allowed to use are being occupied by the execution of the original service method and patiently wait - DEADLOCK.  This is exactly what was happening.  Solution?  Change the ConcurrencyMode to ConcurrencyMode.Reentrant.  This gives WCF permission to abandon the original thread lock on the service and fire the callback.  Much to my surprise, this didn't solve the problem with my windows forms app blocking.  In fact I didn't notice any difference at all.

It was only after spending a few more hours with Juval Lowy's excellent book : Programming WCF Services this weekend that I was able to isolate the problem to one that involved the client's use of SynchronizationContext.

SynchronizationContext is a new beast in .Net 2.0 and affords you the ability to affinitize thread execution.  What does that mean?  Well, one example of its use is where I want to guarantee that some method executes on the same thread that the UI is running on in my windows app.  By applying the use of a synchronization context I can make this guarantee, asking .Net to marshal the thread of execution onto the thread that the UI is running on. 

In WCF there are several mechanisms available to tweak the behavior of the SynchronizationContext for different aspects of your services, but the one that concerns us here is the one that affects the affinity of the thread that the client's callback thread is dispatched on.  By default callbacks are set up to affinitize to the SynchronizationContext of the thread that creates them.  In our case, the UI thread created our callback object and execution of our callback was bound to the UI thread.  This created a problem because we were also dispatching our original call to the Add method on the UI thread.  The callback couldn't be invoked because it was in a deadlock waiting on the original call to Add to complete.  This is why when the timeout exception was thrown, the callback finally was able to get through.

To change this behavior, you can set the UseSynchronizationContext parameter of the CallbackBehavior  attribute to false, indicating that the callback should not be affinitized to the thread that creates the callback.

The fixed portions of our failing code are below:

 

First change the ConcurrencyMode to Reentrant:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
        ConcurrencyMode=ConcurrencyMode.Reentrant)]
    public class CalculatorService : ICalculatorService
    {

...

 

Second, change the CallbackBehavior of the object implementing our service's callback

[CallbackBehavior(UseSynchronizationContext=false)]
    public partial class Form1 : Form, ICalculatorServiceCallback
    {
        ICalculatorService proxy;
        public Form1()
        {
            InitializeComponent();

...

 

I certainly hope this helps save someone some time. 

8/3/2007 12:03 AM (UTC+05:30)
by aaron

For the first time since I can remember, Elizabet and I put aside all of our work and various to-do lists and took off to see a movie in the middle of the week.  We had quite a few movie options because its also actually been quite a while since we've been to the theater at all.  Out of "Knocked Up", "Live Free, Die Hard", "Transformers", and "Ratatouille" the obvious choice was of course "Live Free Die Hard".   It sounded fun and after the last few days... we both really needed a dose of fun. 

 I guess I arrived fairly uninitiated because what I really wasn't prepared for in this movie at all were all the tech / computer / geek references.  Actually "references" is an understatement.  The entirety of the plot is centered around a terrorist-style computer hacking incident of mythical proportions.  Ultimately it was one implausible scenario after another, ultimately culminating in Bruce dodging a very lethal attack from a F-35 Joint Strike Fighter... which was really fun to watch - have you come to expect anything less from a Die Hard sequel? 

I'm tempted to say that I think I got an extra level of enjoyment out of it over the non-geek movie goer simply because in an attempt to follow the "geek dialog" it became painfully obvious that they were totally making stuff up.  In one of the first scenes, when the FBI's computer systems have just been hacked, one FBI dude turns to another and says something like "Our system has been compromised from the outside... its not DOS level but they definitely cracked the door.  What the heck does that mean?  It was almost as if the writer just had to show off the fact that they knew the acronym for Denial of Service even though it didn't quite fit. 

I think my favorite part though was during a hacker vs hacker type scene where one geek causes another geek's computer to start displaying all kinds of pop-up ads for Viagra, sex toys and whatever else.  What a great example of the filmmaker taking something totally incomprehensible to the common citizen - computer hacking - and making it something that they can relate to - pop up ads.  Genius.  Its at that point where the hacker who has just been inundated with flashing Viagra ads yells -- "Its an e-bomb!".  Awesome!  I'm already trying to figure out how to work that one into some code comments on my next project.