Tuesday, May 29, 2012

WCF Service Diagnostics Part 2

In the previous post on this topic I gave an outline of the most common tools used to look into problems with WCF.  In this post I'll give some more information on more advanced tools and approaches for more insidious problems.

SOAP Xml verfication.
It is quite common to use WCF services as the boundaries between different parties or boundaries between responsibilities of teams.  Just like defining an interface so two developers can work on either side in parallel, one developing the interface implementation and the other the consumer; so can service WSDL be used.  In this scenario parties often swap SOAP xml requests and responses as files and check them against their own code.

Tools that can be used are:

  • SOAP UI. Basically this tool allows you to copy and paste SOAP Xml into its UI and then send it to a service.  It will also allow you to see the response SOAP.  Obviously however it is specific to the SOAP protocol and HTTP. It does appear to have loads of other functionality that could be useful particularly for JAVA based diagnostics.
  • Fiddler can be used as well.  I have used it to look and record the HTTP traffic before, but apparentely you can also use it as a proxy to return preconfigured responses as well (although I personally haven't tried this).
  • WsdlSoapXmlValidator. This is a rough tool I have written to take request and response SOAP xml and verify them against the embedded XSD schemas within WSDL (it assumes the WSDL includes Schema and will not work otherwise) and then host a dummy service compliant with the WSDL and using the request and response xml against the service to test actual WCF deserialisation of the samples.
  • WireShark is another tool I have reached for on odd occasions to view network traffic. This is useful for TCP/IP and binary based protocols.
  • WCF Load Test Tool. This is a free codeplex tool written by the Visual Studio ALM Rangers.

Calls between layers should be WCF service calls

Everyone knows about creating layers in software architecture.  During the IDesign Architecture Clinic I attended in March Juval talked about separation of layers and stopping leaking of concerns between layers.
The best way to achieve this is by using WCF between layers.  When this is applied correctly WCF will provide:
Consistency between layers (transactions);
Scalability (general code performance, farming, or partitioning layers onto different app-servers etc);
Fault isolation (resilience from unhandled exceptions and isolate each thread from another's exceptions);
Security (message encryption, transport encryption, authentication, impersonation etc);
Clean Separation of presentation from business logic (maintainability and flexibility);
Availability (striving for 24/7 99.99% up time);
and Synchronisation.

Juval Lowy: "Tell me which one of these you don't like and I'll tell you in which way your system is going to die." (reference)

Juval is also known for saying "...every class as a service...". This might be a little controversial and extreme, but imagine for a moment that the cost of serialisation and deserialisation was eliminated for internal App-Domain calls.  Why would you not want all the above aspects WCF brings to the table not only between layers but also between classes?  An insight into the future perhaps?

Dictionary is not thread safe

No surprises, dictionary is not thread safe.  But what if you're using it with guaranteed unique keys; ie each thread is guaranteed to be accessing it with a key unique to only that thread?

Here's a test:

private static readonly Dictionary<string, string> dictionary = new Dictionary<string, string>();

     public static void Main(string[] args)
            var threads = new List<Thread>();
            for (int threadNumber = 0; threadNumber < 100; threadNumber++)
                int number = threadNumber;
                var thread = new Thread(
                    () =>
                        for (int index = 0; index < 1000; index++)
                            Console.WriteLine("Thread" + number + " index " + index);
                            var key = Guid.NewGuid().ToString();
                            dictionary.Add(key, "Value");
                            var dynamicValue = Guid.NewGuid().ToString();
                            dictionary[key] = dynamicValue;
                            Debug.Assert(dictionary[key] == dynamicValue);

            foreach (var thread in threads)

So, as you can see, this is creating a bunch of threads that all hammer the dictionary adding and editing and then asserting everything is as it should be. This runs fine with no exceptions. Or does it...

Comment the Console.WriteLine and it no longer runs...

So what is happening here?  As the dictionary gets larger the it will need to change its internal storage to increase its size, when this occurs another thread will either corrupt it or access stale data. So bad news.

The morale of the story is always add a Console.WriteLine before accessing a dictionary. Just kidding. If you think there will be any sort of multi-thread contention use a ConcurrentDictionary instead.  Just simply by thinking each thread accessing the dictionary using a guaranteed unique key will not suffice.

Sunday, May 6, 2012

Version 1.0.16 of Type Visualiser

A new version of Type Visualiser is available. See the Type Visualiser page for download details.

I've added a new mulit-document interface using tabs to allow many diagrams to be open at once.  I found this is need when using the tool for any serious discovery of unfamilar code.

Unlike the standard WPF tab control I have written my own to ensure individual tabs are kept in memory for fast switching between tabs.  This will consume memory the more tabs you open, but waiting between tab switch didn't feel like a good user experience.  As types are loaded they are also stored in a global cache to prevent analysing the same type twice even for different diagrams.  

I'm currently looking at changing the way I've implemented zooming, panning and centreing to a far better approach. This will allow for animations when zooming and for infinite canvas size that expands when diagrams push the boundaries of the diagram.