Programming, Policitcs, and uhhh Pineapples.
# Friday, June 19, 2009

I Learned A New Vocabulary Word Today...

Friday, June 19, 2009 3:32:47 PM UTC

Apophallation.

Apophallation is a technique resorted to by some species of air-breathing land slugs such as Limax maximus and Ariolimax spp. In these species of hermaphroditic terrestrial gastropod mollusks, after mating, if the slugs cannot successfully separate, a deliberate amputating of the penis takes place.

The slugs are hermaphroditic and have a full set of organs of both sexes. They have relatively large penises which, during mating, wrap around each other in a tight spiral. They sometimes have difficulty separating afterwards. When separating seems impossible, one slug gnaws off either its own, or its partner's penis, so that separation is then possible. No replacement penis grows, and the apophallated slug adopts a purely female function from that point onward.

:-O

(We've been having a pretty heavy slug infestation due to the inordinate amount of rainfall we've been getting...luckily, they don't seem to like pineapple)

As if that wasn't fascinating enough, their sex organs protrude from the side of their head.

And if that didn't boggle your mind, how about eating slugs (warning: cute and gag inducing at the same time)?

Youtube.

# Friday, June 12, 2009

Discovering System.Linq.Expressions

Friday, June 12, 2009 3:24:08 AM UTC

I'm officially a fan: System.Linq.Expressions is one of the coolest namespaces.

I've been working on a simple workflow engine as an example codebase for exploring different aspects of object oriented programming (inheritance, encapsulation, polymorphism, design patterns, etc.) for training purposes.

As a side note, I've found that it's actually very difficult to describe good object oriented code; I can just kind of feel it when I'm writing it and I know it when I see it...but it's really, really hard to describe.  I was asked by an associate consultant why it mattered.  Why bother with good object oriented design?  For me (at least), more than anything, it's about organization of code, readability, maintainability, and usability.  Good object oriented code makes it easy to think about the models and how the interactions between the different moving parts are executed.  But that's a bigger topic for a different post.

Back on topic :-D The basic design scenario that I was trying to solve in this case is that the simple workflow engine (SWE) would have the capability of hydrating a workflow template instance from an XML definition file (much like WF does with .xoml files, but on a much more basic level, of course).  I thought this would be a good exercise for teaching purposes as it would cover various aspects of reflection.  Somewhere along the line, inspired by a comment by Richard Deeming (see bullet #4) on Rick Strahl's DataContextFactory implementation, I decided to see if I could do it using expression trees instead.

Here is a sample XML template definition:

<WorkflowTemplate>
    <Actions>
        <Action Type="SimpleWorkflowEngine.Extensions.CustomActions.EmailAction, 
            SimpleWorkflowEngine.Extensions">
            <Parameters>
                <Parameter Name="ContinueOnError">true</Parameter>
                <Parameter Name="FriendlyName">Send Email</Parameter>
                <Parameter Name="RecipientAddress">cchen@domain.com</Parameter>
                <Parameter Name="Message">Hello, World! From SimpleWorkflowEngine!</Parameter>
                <Parameter Name="Subject">Test Email</Parameter>
            </Parameters>
        </Action>
    </Actions>
</WorkflowTemplate>

Here are the classes which this XML deserializes to:

using System;
using System.Collections.ObjectModel;
using System.Xml.Serialization;

namespace SimpleWorkflowEngine.Core.Common
{
    /// <summary>
    /// Models a workflow template.
    /// </summary>
    [Serializable]
    [XmlRoot("WorkflowTemplate")]
    public class WorkflowTemplate
    {
        private Collection<WorkflowTemplateAction> _actions;

        /// <summary>
        /// Gets or sets the actions for this workflow template.
        /// </summary>
        /// <value>The actions.</value>
        [XmlArray("Actions"), XmlArrayItem("Action", 
            typeof(WorkflowTemplateAction))]
        public Collection<WorkflowTemplateAction> Actions
        {
            get { return _actions; }
            set { _actions = value; }
        }
    }

    /// <summary>
    /// Represents an action in the workflow.
    /// </summary>
    [Serializable]
    public class WorkflowTemplateAction
    {
        private string _typeName;
        private Collection<WorkflowTemplateParameter> _parameters;

        /// <summary>
        /// Gets or sets the type name of the concrete 
        /// <see cref="WorkflowAction"/> class.
        /// </summary>
        /// <value>
        /// The type name of the concrete <see cref="WorkflowAction"/> class.
        /// </value>
        [XmlAttribute("Type")]
        public string TypeName
        {
            get { return _typeName; }
            set { _typeName = value; }
        }

        /// <summary>
        /// Gets or sets the parameters which map to property values on 
        /// the action.
        /// </summary>
        /// <value>The parameters.</value>
        [XmlArray("Parameters"), XmlArrayItem("Parameter", 
            typeof(WorkflowTemplateParameter))]
        public Collection<WorkflowTemplateParameter> Parameters
        {
            get { return _parameters; }
            set { _parameters = value; }
        }
    }

    /// <summary>
    /// Represents a property value on the <see cref="WorkflowAction"/>.
    /// </summary>
    [Serializable]
    public class WorkflowTemplateParameter
    {
        private string _name;
        private string _value;

        /// <summary>
        /// Gets or sets the name.  It must match the name of the property.
        /// </summary>
        /// <value>The name of the property.</value>
        [XmlAttribute("Name")]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        [XmlText(typeof(string))]
        public string Value
        {
            get { return _value; }
            set { _value = value; }
        }
    }
}

I've done something similar in a workflow engine that I put together for Zorch Software before the days of WF. Back then I used reflection to assemble a workflow instance from an XML template as well. (In that case, the engine supported state machine workflows; for this training sample, I thought that just sequential was good enough)

Here is the invocation code to get a new instance of a workflow from a workflow template definition:

using System;
using MbUnit.Framework;
using SimpleWorkflowEngine.Core.Common;
using SimpleWorkflowEngine.Core.Contracts;
using SimpleWorkflowEngine.Core.Runtime;

namespace SimpleWorkflowEngine.Tests.Fixtures
{
    [TestFixture]
    public class WorkflowFactoryTests
    {
        [Test]
        public void TestCreateInstance()
        {
            IWorkflowTemplateProvider provider =
                ApplicationContext.Instance.Resolve<IWorkflowTemplateProvider>();

            WorkflowTemplate template =
                provider.FromTemplateId(
                new Guid("1FE5526C-D0E7-4c58-8644-3B3144AEED0E"));

            Workflow instance = WorkflowFactory.Create(template);

            Assert.AreEqual(1, instance.Actions.Count);
        }
    }
}

The basics are that the factory has to create an instance by iterating through each WorkflowTemplateAction and creating a concrete WorkflowAction instance and set property values using the WorkflowTemplateParameter associated with the WorkflowTemplateAction.

Here is the implementation of the factory method (cool stuff in bold):

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using SimpleWorkflowEngine.Core.Common;

namespace SimpleWorkflowEngine.Core.Runtime
{
    /// <summary>
    /// Assembles a workflow instance based on an input template.
    /// </summary>
    public static class WorkflowFactory
    {
        private static string _nullPropertyError = 
            "The parameter \"{0}\" did not match a property on the class \"{1}\".";

        /// <summary>
        /// Assembles a workflow instance from a workflow template instance.
        /// </summary>
        /// <param name="template">The template.</param>
        /// <returns>A workflow instance based on the workflow template.</returns>
        public static Workflow Create(WorkflowTemplate template)
        {
            Workflow instance = new Workflow();

            foreach(WorkflowTemplateAction templateAction in template.Actions)
            {
                Type actionType = Type.GetType(templateAction.TypeName);               

                List<MemberBinding> bindings = new List<MemberBinding>();

                foreach(WorkflowTemplateParameter parameter in templateAction.Parameters)
                {
                    BindingFlags flags = BindingFlags.SetProperty 
                        | BindingFlags.Instance | BindingFlags.Public;

                    // Get the property matching the parameter name.
                    PropertyInfo property = actionType.GetProperty(
                        parameter.Name, flags);

                    if(property == null)
                    {
                        throw new NullReferenceException(string.Format(
                            _nullPropertyError, parameter.Name, actionType.Name));
                    }

                    // Convert the parameter value type.
                    object value = Convert.ChangeType(
                        parameter.Value, property.PropertyType);

                    // Create an assignment binding (set the property value).
                    MemberAssignment binding = Expression.Bind(
                        property, 
                        Expression.Constant(value, property.PropertyType));

                    bindings.Add(binding);
                }

                // Create the code expression and execute it to get a new instance.
                MemberInitExpression init = Expression.MemberInit(
                    Expression.New(actionType), bindings);

                WorkflowAction action = Expression.Lambda<Func<WorkflowAction>>(init)
                    .Compile().Invoke();

                // Add the action to the workflow.
                instance.Actions.Add(action);
            }

            return instance;
        }
    }
}

The outer for loop iterates the actions to create and the inner for loop collects the properties to set on the action.  Object creation and initializaiton is done in one shot using Expression.Lambda.

For reference, here is the target class for the XML in the sample above:

using System;
using SimpleWorkflowEngine.Core.Attributes;
using SimpleWorkflowEngine.Core.Common;
using SimpleWorkflowEngine.Core.Constants;
using SimpleWorkflowEngine.Extensions.Components;

namespace SimpleWorkflowEngine.Extensions.CustomActions
{
    /// <summary>
    /// A worflow action which sends an email to a recipient.
    /// </summary>
    public class EmailAction : WorkflowAction
    {
        private MailClientService _mailClientService;
        private string _message;
        private string _recipientAddress;
        private string _subject;

        /// <summary>
        /// Sets the mail client service.
        /// </summary>
        /// <value>The mail client service.</value>
        public MailClientService MailClientService
        {
            set { _mailClientService = value; }
        }

        /// <summary>
        /// Gets or sets the recipient address.
        /// </summary>
        /// <value>The recipient address.</value>
        [Parameter(Usage.IsRequired, "Recipient e-mail")]
        public string RecipientAddress
        {
            get { return _recipientAddress; }
            set { _recipientAddress = value; }
        }

        /// <summary>
        /// Gets or sets the message.
        /// </summary>
        /// <value>The message.</value>
        [Parameter(Usage.IsRequired, "Message")]
        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }

        /// <summary>
        /// Gets or sets the subject.
        /// </summary>
        /// <value>The subject.</value>
        [Parameter(Usage.IsRequired, "Subject")]
        public string Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }

        /// <summary>
        /// Gets a value indicating whether this instance 
        /// [requires input].
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance [requires input]; 
        /// otherwise, <c>false</c>.
        /// </value>
        public override bool RequiresInput
        {
            get { return false; }
        }

        /// <summary>
        /// Inheriting member should override this method to implement 
        /// custom execution logic.
        /// </summary>
        /// <param name="context">The context.</param>
        protected override void OnExecute(ExecutionContext context)
        {
            if (_mailClientService == null)
            {
                throw new NullReferenceException(
                    "No mail service client is configured for this runtime.");
            }

            _mailClientService.SendMail(RecipientAddress, Subject, Message);
        }
    }
}

Admittedly, I didn't expect this to work...I had a hell of a time figuring out how to create the expression to set the property values.

# Tuesday, June 09, 2009

I Like Jeffrey Palermo's Prediction...

Tuesday, June 09, 2009 4:15:49 PM UTC

I've been playing around with ASP.NET MVC for about a week now and it does everything right that ASP.NET web forms did so wrong.  I've hated ASP.NET web forms with a passion as soon as I realized that the model was terrible for the majority of development shops in terms of managing unmanageable code jumbles -- huge methods written on event handlers...

Don't get me wrong, ASP.NET 1.0 was a huge step up from classic ASP, but it has exploded into this huge culture of control based RAD developers.  Not that you couldn't roll your own MVC pattern for ASP.NET, but having it as an officially supported development model should help bring more web developers out from the grips of the dark side.

Most consultants (even "senior" ones) simply take the quick-and-dirty route when it comes to ASP.NET web forms development, dragging and dropping controls all day long.  Not that it's a bad thing...for prototyping, but it quickly devolves into hard to manage, hard to maintain, and difficult to test codebases with very low levels of reusability.  This is especially true once you roll on junior or mid level developers to a web project.

Earlier in the year, Jeffrey Palermo predicted that MVC would replace web forms as the dominant web application development model on the .NET platform.  With the recent news of MVC 2, Palermo reasserts his prediction with even greater conviction.  I was already long convinced that ASP.NET web forms was a craptastic model for web application development, but I had some skepticism about MVC (after my pretty awesome experience with Django).  This past week has convinced me that MVC kicks ass and I hope that Jeffrey's prediction is right.

I wholeheartedly agree; I simply can't wait to dump ASP.NET web forms.

# Friday, June 05, 2009

T-SQL MERGE: My New Friend

Friday, June 05, 2009 3:49:08 PM UTC

As I was catching up on SQL 2008 this morning, I spent some time working with the T-SQL MERGE command, new in SQL 2008.  Most of the blogs and examples online are a bit terse, so I decided to write a simple sample.

Check it out:

--// Create our SOURCE table
DECLARE @t1 TABLE (
    id      int,
    name    nvarchar(16),
    email   nvarchar(32)
)

--// Create our TARGET table
DECLARE @t2 TABLE (
    id      int,
    name    nvarchar(16),
    email   nvarchar(32)
)

--// Insert values into SOURCE table
INSERT INTO @t1 VALUES (1, 'Charles Chen', 'charles.chen@domain.com')
INSERT INTO @t1 VALUES (2, 'Sandra Chen', 'sandra.chen@domain.com')
INSERT INTO @t1 VALUES (3, 'Brad Wright', 'brad.wright@domain.com')

--// Insert values into TARGET table
INSERT INTO @t2 VALUES (4, 'Brady Sines', 'brady.sines@domain.com')
INSERT INTO @t2 VALUES (1, '', '')

--// Select values from the TARGET table (just to verify)
SELECT * FROM @t2

--// Merge records from source to target
MERGE
    @t2 AS [target]
USING
    @t1 AS [source]
ON
    ([target].id = [source].id)
WHEN NOT MATCHED BY TARGET
    THEN
        INSERT(id, name, email)
        VALUES([source].id, [source].name, [source].email)
WHEN MATCHED
    THEN
        UPDATE SET
            [target].name = [source].name,
            [target].email = [source].email
--// Get the journal of actions
OUTPUT $action, inserted.*, deleted.*;

--// Grab the resultant table
SELECT * FROM @t2

And here are the results:

Awesome!  Admittedly, I'm still trying to come up with some legitimate uses for this in my day-to-day application programming :-D

# Thursday, June 04, 2009

QOTD

Thursday, June 04, 2009 6:16:25 PM UTC

A friend passed along a quote the other day:

So I just picked up this book today....and found this quote in the forward: "The truth of the matter is, if you need to “save” your job, I can’t help you. This book isn’t about struggling to maintain the level of mediocrity required not to get fired. It’s about being awesome. It’s about winning. You don’t win a race by trying not to lose. And you don’t win at life by trying not to suck. Fortunately, the content of the book has never been about trying not to suck. I can’t think that way, and neither should you."

Thanks, Dan!

# Thursday, May 28, 2009

Visitor Pattern In C# 4.0

Thursday, May 28, 2009 7:19:17 PM UTC

I've blogged about the Visitor pattern previously and using double dispatch to resolve .NET's inherent inability to resolve methods by parameter type at runtime.

As I was reading about C# 4.0's dynamic types, I started to wonder if this would mean that we could finally get a more concise implementation of the pattern.  My hunch was correct.

Here is the updated code listing (key changes bolded):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace VisitorPatternConsole
{
    public class Program
    {
        private static void Main(string[] args)
        {
            // NOTE: Using dynamic collections.
            Collection<dynamic> visitors 
				= new Collection<dynamic>();
            Collection<dynamic> pets 
				= new Collection<dynamic>();
 
            // Initialize the pets
            pets.Add(new Fish());
            pets.Add(new Dog());

            // Initialize the visitors
            visitors.Add(new Feeder());
            visitors.Add(new Walker());

            // Visit each of the pets.
            foreach (dynamic pet in pets)
            {
                foreach (dynamic visitor in visitors)
                {
                    visitor.Visit(pet);
                }
            }

            // Check the results.
            foreach (Pet pet in pets)
            {
                Console.Out.WriteLine(pet.GetType().Name);
                foreach (String note in pet.Visitors)
                {
                    Console.Out.WriteLine("\t{0}", note);
                }
            }
        }
    }

    /// <summary>
    /// Handles the base cases.
    /// </summary>
    public abstract class AbstractVisitor
    {
        public void Visit(Pet pet)
        {
            pet.Visitors.Add(
                "Not supported for this type of pet...");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet feeder.
    /// </summary>
    public class Feeder : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            // Feed the dog
            dog.Visitors.Add("Fed the dog");
        }

        public void Visit(Fish fish)
        {
            // Feed the fish
            fish.Visitors.Add("Fed the fish");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet walker.
    /// </summary>
    public class Walker : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            dog.Visitors.Add("Walked the dog");
        }

        // Fish can't be walked!
    }

    /// <summary>
    /// Base class for pets.
    /// </summary>
    public abstract class Pet
    {
        private readonly Collection<string> visitors;

        public Collection<string> Visitors
        {
            get { return visitors; }
        }

        protected Pet()
        {
            visitors = new Collection<string>();
        }
    }

    /// <summary>
    /// A pet fish.
    /// </summary>
    public class Fish : Pet { }

    /// <summary>
    /// A pet dog.
    /// </summary>
    public class Dog : Pet { }
}

Here is the output:

Wow, just when I thought dynamic was going to suck :-D

What is somewhat interesting is that both collections have to be declared of type dynamic; I'm still mulling this over, but it's not clear why it doesn't work if only one of the collections is declared dynamic (I figured that it should have worked if the visitors collection alone was declared dynamic).

# Wednesday, May 27, 2009

Random DevTools Entry #017

Wednesday, May 27, 2009 10:27:01 PM UTC

In software development, it's incredibly useful to be able to visualize your code interactions using sequence diagrams and data flow diagrams and what not.  Not only is the visualization a plus, the act of generating one helps tremendously in terms of working out the outline of the logic that you need to implement.  One of the biggest problems I've come across in this area are the tools: they're simply too heavy and too complex for general diagram drawing tasks in addition to being generally rigid as well.

Today, as I was about to download and install Visio, I decided to spend a few minutes checking to see if there was a web alternative.  Enter websequencediagrams.  This is an all around awesome little tool to add to your toolbox.  Not only is it free (free is always awesome), it's text based.  At first blush, this seems terrible; there's a whole syntax to learn and lots of typing.  But the syntax is incredibly easy and simple while powerful and easy to understand.

Here's an example (I've bolded the syntax to make it easier to distinguish):

Browser->App: HandleSearchClickEvent()
App->Service: ExecuteSearch(keyword)
activate Service
Service-->App: (return results)
deactivate Service
App->App: RenderResults(reseults)
note right of App:
    render URL with
    keyword in query string.
end note
App-->Browser: HTML
Browser-->Office: click:
http://../name.docx?term=keyword
Office->AddIn: ThisAddIn_Startup()
AddIn->AddIn: Check for search term
note left of AddIn:
    ActiveDocument.FullName will
    contain the query string.  This
    can be extracted with a regular
    expression
end note
AddIn->AddIn: Execute find

And here is the result:

There are also a variety of pre-defined styles you can choose to render your diagram.  It's all sorts of awesome and a real time-saver compared to traditional tools.  I personally love that it's text based; I've found that when working with Visio (and other such tools), more than half of my time is spent arranging things just to get them to line up.  A text based approach works well for sequence diagrams and gets rid of that layer of unnecessary complexity.

# Friday, April 17, 2009

WCF Load Balancing : An End To End Example For NetTcpBinding

Friday, April 17, 2009 6:17:08 PM UTC

Recently, I worked on prototyping WCF load balancing for our product, FirstPoint.  I built a simple example to test the configuration and behavior of load balancing.  Since there aren't many end-to-end examples of WCF load balancing on the web, I'm hoping this will be useful (since the Microsoft documentation on this is basically non-existent...well, for NetTcpBindings at least).

I will assume that you are already familiar with network load balancing and configuring the NLB on Windows Server 2003.

Here's a screenshot of how I've configured my network load balancer:

You'll notice that I've configured a specific port range for my service.  Also, take note of the cluster address: 192.168.1.220.  The two servers that make up the cluster are FPDEV1 (192.168.1.222) and FPDEV2 (192.168.1.223).

I've defined a simple service interface which simply echoes the message with a server name:

using System.ServiceModel;

namespace WcfLoadBalancingSample.Server.Contracts {
    /// <summary>
    /// A simple service contract definition which defines an echo operation.
    /// </summary>
    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface IEchoService {

        /// <summary>
        /// Echoes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>The input message with a server identifier attached.</returns>
        [OperationContract]
        string Echo(string message);
    }
}

And here is the implementation:

using System;
using WcfLoadBalancingSample.Server.Contracts;

namespace WcfLoadBalancingSample.Server.Services {
    /// <summary>
    /// Implements the <c>IEchoService</c>.
    /// </summary>
    public class EchoService : IEchoService {
        #region IEchoService Members

        /// <summary>
        /// Echoes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>
        /// The input message with a server identifier attached.
        /// </returns>
        public string Echo(string message) {
            return string.Format("[{0}] {1}", Environment.MachineName, message);
        }

        #endregion
    }
}  

As you can see, I've simply prepended the machine name to each response so that we can track which server we are connecting to. Here is the main program which hosts the service:

using System;
using System.ServiceModel;
using WcfLoadBalancingSample.Server.Services;

namespace WcfLoadBalancingSample.Server {
    internal class Program {
        private static void Main(string[] args) {
            var program = new Program();
            program.Run();
        }

        public void Run() {           
            ServiceHost serviceHost = null;

            try {
                serviceHost = new ServiceHost(typeof (EchoService));
                serviceHost.Open();

                Console.Out.WriteLine("Service ready.");
                Console.Out.WriteLine("Press any key to terminate.");
                Console.Out.WriteLine("============================");
                Console.ReadKey();
            }
            catch (Exception exception) {
                Console.Out.WriteLine(exception);
                Console.ReadKey();
            }
            finally {
                if (serviceHost != null) {
                    serviceHost.Abort();
                }
            }
        }
    }
}  

This should be deployed on your each of your two (or more) servers in your cluster.  The magic comes next in the configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            <service name="WcfLoadBalancingSample.Server.Services.EchoService"
                     behaviorConfiguration="WcfLoadBalancingSample.Server.Services.EchoServiceBehavior">
                <!-- Service Endpoints -->
                <!--///
                    The configured endpoint address is the IP address of the load balanced
                    cluster.  The port number has been mapped to the cluster.
                ///-->
                <endpoint
                    address ="net.tcp://192.168.1.220:12345/lb/EchoService"
                    binding="customBinding"
                    bindingConfiguration="DefaultCustomBinding"
                    contract="WcfLoadBalancingSample.Server.Contracts.IEchoService">
                </endpoint>
            </service>
        </services>
        <bindings>
            <!--///
                A simple custom binding.  Note the leaseTimeout setting.
                This is referenced in the SDK documentation, but not described
                in any way as to how you're supposed to configure it.
            ///-->
            <customBinding>
                <binding name="DefaultCustomBinding">
                    <windowsStreamSecurity protectionLevel="None"/>
                    <binaryMessageEncoding/>
                    <tcpTransport>
                        <connectionPoolSettings leaseTimeout="00:00:01"/>
                    </tcpTransport>
                </binding>
            </customBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="WcfLoadBalancingSample.Server.Services.EchoServiceBehavior">
                    <serviceMetadata httpGetEnabled="True"
                                     httpGetUrl="http://192.168.1.220/lb/EchoService/MEX"/>
                    <serviceDebug includeExceptionDetailInFaults="True" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

The most important part of this configuration file is the setting for the lease timeout. The SDK documentation references this setting, but does not go into detail on how it's configured.  Note that it seems that you can only set the least timeout value in configuration using a custom binding.

There is one particularly important thing to note here: I've set the timeout to 1 second for demonstration purposes only.  The SDK documentation mentions that this value should be set to 30 seconds.  As we'll see later, I have the client creating a new connection every 2.5 seconds (on purpose so we can test connectivity).  What I found was that with the default setting (5 minutes, according to the SDK), if you initially connect to server A and server A goes down, it will not automatically connect to server B.  I assume this is because of the lease timeout value (it throws an exception).

Also note that the endpoint is configured using the IP address of the node balancing cluster and not the individual servers.

The client side of it is pretty straight forward as well:

using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using WcfLoadBalancingSample.Client.LoadBalancedService;

namespace WcfLoadBalancingSample.Client {
    public delegate void EchoDelegate();

    public class EchoEventArgs : EventArgs {
        public EchoEventArgs(string message) {
            Message = message;
        }

        public string Message { get; set; }
    }

    internal class Program {
        private static void Main(string[] args) {
            var program = new Program();
            program.Run();
        }

        public void Run() {
            // Start the server.
            Console.Out.WriteLine("Starting client...(press any key to exit)");

            // Start second thread to ping the server.
            EchoDelegate echoDelegate = EchoAsync;
            echoDelegate.BeginInvoke(EchoAsycCompleted, null);

            Console.Read();
        }
        
        /// <summary>
        /// Asynchronous execution of the call to the server.
        /// </summary>
        private void EchoAsync() {
            try {
                int count = 0;
                while (true) {
                    using (var serviceClient = new EchoServiceClient()) {
                        // Call the echo service.
                        string result = serviceClient.Echo(
                            count.ToString());

                        Console.Out.WriteLine(result);

                        count++;                        
                    }

                    Thread.Sleep(2500);
                }
            }
            catch (Exception exception) {
                Console.Out.WriteLine(exception);
            }
        }

        /// <summary>
        /// Handles the completion of the thread.
        /// </summary>
        /// <param name="result">The result.</param>
        private void EchoAsycCompleted(IAsyncResult result) {
            var r = (AsyncResult) result;
            var e = (EchoDelegate) r.AsyncDelegate;

            e.EndInvoke(r);
        }
    }
}

The only thing to note is that I used a delegate to spin off a second thread to make the call to the server.  Adding a reference to the server generates the following configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="CustomBinding_IEchoService">
                    <security mode="Transport">
                        <transport clientCredentialType="Windows" 
                                   protectionLevel="None" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint 
                address="net.tcp://192.168.1.220:12345/lb/EchoService"
                binding="netTcpBinding" 
                bindingConfiguration="CustomBinding_IEchoService"
                contract="LoadBalancedService.IEchoService" 
                name="CustomBinding_IEchoService">
                <identity>
                    <userPrincipalName value="Administrator@fpdev.com" />
                    <servicePrincipalName value="" />
                    <dns value="192.168.1.220" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Note that on this side, the binding is generated as a netTcpBinding.

And that's it!  Deploy the service to your clustered servers and start the services and then start the client.  If your cluster has a bias towards one server, you will see that the messages will come from that server.  To test that it actually is load balancing, simply stop the service on that server and you should see that the output will be coming from the other server.  Here's an example:

You can see that after I stop the service on FPDEV1 at the third echo message, it flips over to FPDEV2!  Awesome!

Here's the full project (VS2008): WcfLoadBalancingSample.zip (16.89 KB)

Obama Says No To The Assault Weapons Ban

Friday, April 17, 2009 1:04:57 AM UTC

So can we stop the bitter tears for a bit?  Just a little?

http://www.msnbc.msn.com/id/30232095

U.S. president signals he won't seek reinstatement of assault weapons ban

MEXICO CITY - Acknowledging a Mexican drug war that is "sowing chaos in our communities," President Barack Obama signaled Thursday he will not seek the reinstatement of a U.S. assault weapons ban but instead step up enforcement of existing laws against taking such weapons across the border.
Despite a campaign promise to see the lapsed ban renewed, Obama was bowing to the reality that to do so would be unpopular in politically key U.S. states and among Republicans as well as some conservative Democrats.

# Thursday, April 16, 2009

CharlieDigital's Guide to "Teabaggin"

Thursday, April 16, 2009 1:00:49 PM UTC

This recent phenomenon of "teabaggin" (lol) amongst conservatives has been humorous on many fronts.  But it's gotten me thinking: are there people really this stupid?  I mean, that's a lot of stupid.  Some of the signs I've seen are pretty creative (creatively wrong).  Let's address some of them and see what we come up with.

I find this one quite humorous myself, as it shows: 1) a total lack of perspective and 2) it's amazing how easily you can get someone to protest against their own self interest.  If this protester didn't know, the highest marginal tax bracket under Reagan was 50%. Then clearly, Ronald Reagan meant 50% slavery right?  So 39% slavery should be an improvement.  Aside from that, what in the right mind of Vishnu are these people thinking?  Do they have any clue on what slavery was really like?  I mean, wow, get some perspective.  On the second point, Obama has already enacted a tax cut (look at your paycheck and you should see it) for 95% of Americans.  Who are the poor, unlucky 5% that have been excluded?  I'm pretty sure its not this guy holding the sign; instead, they're folks making well into 6 figure territory.

There is great amusement to be found in this picture as well.  "ZERO TAXES"?  I wonder how this old lady thinks the roads she is sitting next to were built?  How were the side walks built?  Who paid for those signals?  Who paid for that sign?  I shudder at the thought of living in a country with zero taxes.  Why?  Because it would be a shithole for all but the super wealthy.  Education and literacy rates would drop dramatically.  Commerce would slowly wither as roads and infrastructure weathered and fell into disrepair.  The old would flood homeless shelters and emergency rooms.  Crime would increase as there would be no publicly funded police...only privately funded militia (no better than paying protection to the mafia).  Zero taxes?  Why not relocate to Somalia instead.

Taxation is a necessary price to pay for living under the protection of the federal government.  It is a necessary price to pay for the services and infrastructure which service us all and enable commerce.  It funds education and improves the quality of life of all Americans (after all, the more children we educate and transform into productive members of society, the better off we are tomorrow).  Paul Begala gets it right:

Happy Patriots' Day. April 15 is the one day a year when our country asks something of us -- or at least the vast majority of us.

For those who wear a military uniform, those who serve the rest of us as policemen and firefighters and teachers and other public servants, every day is patriots' day. They work hard for our country; many risk their lives -- and some lose their lives.

But for the rest of us, the civilian majority, our government asks very little. Except for April 15. On this day, our government asks that we pay our fair share of taxes to keep our beloved country strong and safe.

He's right: aside from paying my taxes, the government does ask very little of me.  I'm neither forced to serve in our armed forces, forced to do any work on behalf of the government, nor am I oppressed.  In exchange for 20% of my income (my effective federal tax rate this year), I get to live in a relatively stable and safe society with some of the greatest degrees of freedoms of any first world country.

Of course, let's not forget that silly lady on the left either.  Excuse me miss, but you can't have defense without taxes (lol).

This one is great, too.  On the contrary, Obama's whole platform is aimed a middle class gains.  His tax policy, cuts for middle class Americans while reverting to the top marginal tax rate under Clinton (bear in mind, this is still lower than the top marginal tax rate under Reagan), seems like it's designed specifically to help working, white collar, middle class Americans.  So either this guy makes more than $200,000 or he's just stupid.  I think it's the latter.

lol. Where do I begin with this one?  I mean, what does Christianity have anything to do with this at all?  First of all, we're not a Christian nation.  Second of all, I love the guy's shirt: "Stupidity Offsets for Sale".  I think he needs to buy crate loads of them.

lol.  Still on this ACORN thing?

This one is particularly funny as Wall Street is the epitome of unfettered capitalism. Somehow, our government has been hijacked by both capitalists and socialists...AT THE SAME TIME! Amusing.

Oh, and apparently facists, too. (I rather think that this quote applies more to these teabaggin' protestors than it does to the rest of the public.)  Also: quoting Hitler on your t-shirt?  Always classy.

This one is ironic because this person has conveniently forgotten that we had this thing called an "election" on November 4, 2008.  Yeah, you know, this thing where millions of people from all across the country come out and select the people whom they choose to represent their interests.  Oh yeah, that's right, your guy lost...silly me.

But more importantly, this sign is patently ridiculous simply because it ignores the reality of how government works.  As if "THE GOV'NT" is some entity of the elite, assembled with individuals from some higher class seeking to oppress the people.  Well, I've got news for you: "THE GOV'NT" is of the people, by the people, and for the people.

I think what gets me even more are the cries of socialism, communism, and facism.  Do these people even know what these terms mean?  I mean, do they? I think these people need to have a talk with this guy:

Of course, another fun game to play with all of these tea party pictures is "Spot the Minority".  There's just something really weird that I can't put my finger on...almost every picture of these crowds is 100% white.  What's the deal with that?

What's that you say? You have more questions. Well, let's hear them.

Where's MY bailout?

Well, that's simple: you're already getting tax cut from the Obama administration.  Aside from this, check out his mortgage rescue plan.

NEW YORK (CNNMoney.com) -- The Obama administration's loan modification program is finally underway.

The Treasury Department announced Wednesday the first six participants to sign up for President Obama's plan. They include three of the nation's largest banks: JPMorgan Chase (JPM, Fortune 500), which will get up to $3.6 billion in subsidy and incentive payments; Wells Fargo (WFC, Fortune 500), $2.9 billion; and Citigroup (C, Fortune 500), $2 billion. The others are GMAC Mortgage, $633 million; Saxon Mortgage Services, $407 million; and Select Portfolio Servicing, $376 million.

Additional loan servicers will be added to the list over time, a Treasury spokesman said.

Billed as helping up to 9 million borrowers stay in their homes, the two-part plan calls for servicers to reduce monthly payments to no more than 31% of eligible borrowers' pre-tax income or to refinance eligible mortgages even if the homeowner has little or no equity. The government is allocating $75 billion to subsidize part of payment reduction, as well as provide thousands of dollars in incentives for servicers and borrowers to participate.

This is a huge bailout of the American Dream; it aims to keep homeowners (or should I say mortgage payers?) in their homes by modifying mortgages to the realities of the current market and economic environment.  Taking advantage of historically low mortgage rates, I've already refinanced and ended up saving some $400/month.  So there's your bailout.

But the national debt is skyrocketing!  Think of the children!

There are a few points to make here.  First, I must direct your attention to the Treasury Department's helpful website on this topic.  Please browse through every date range on the site.  Notice a pattern?  That's right, every generation since 1791 has left a debt. Every.  Single.  One. 

Of course, one of the fun facts is looking at the national debt between 9/30/2001 and 9/30/2008, roughly President Bush's two terms.  Let's see, it started at 5.8 trillion, and, well, looky here, ended at 10 trillion.  Whoa, I thought, like, Republicans were supposed to be all conservative-like.  Guess that's just a myth!  Let's look at another time period.  How about Reagan's presidency, the period between 9/30/1982 and 9/30/1988.  Let's see, it started at 1.1 trillion and it ended at 2.6 trillion. Will you look at that?  Ronald Reagan more than doubled the national debt. 

But let's move on from the numbers; I'm sure you protested when Bush and Reagan were in charge, too, right? 

There's another point to be made that can't be made with numbers and that's the fact that not all debt is created equally.  There are multiple parts to this.  The first is the interest rate on debt.  It has never been cheaper to create debt than it is right now since intrest rates are so depressed. Secondly, consider this question: is borrowing $40,000 to spend on a sports car the same as spending $40,000  on a graduate degree?  If your jobless sibling came to you tomorrow and asked to borrow $10,000 to buy a new motorcycle, would you react the same way as if he came and borrowed $10,000 to go back to school?

Of course there is a big difference.  One is a depreciating asset from which you are not likely to ever see any returns on and the other, an education, has a great potential to generate a high return on investment.  Likewise, spending on education, healthcare, infrastructure, basic scientific research, and developing energy solutions is an investment that is likely to yield a high return on investment.  It is spending that increases our overall capacity for commerce.  You need an educated population for high paying jobs, you need working roads to facilitate commerce, you need a new energy grid for efficiency (cost savings) and security, you need to fund basic research to drive innovation, you need to fix healthcare because it is one of the biggest factors depressing wages in the US.

If there is something that we should spend our tax dollars on, it's things like these, things that willl someday help generate commerce and thus employment and tax revenues.  And of course, keep in mind, our kids will utilize these same roads and infrastructure decades down the line.  The will go to these new schools.  They will be the beneficiaries of increased grants for scientific research.  It is precisely the next generation that will benefit the most from our investment today.

RSS 2.0 Atom 1.0 CDF