stuff i do at work

(maybe i’ll make less mistakes if i remember some)

Archive for June, 2008

Redundancy and failover

Posted by noah on June 25, 2008

Recently, I rewrote a quote service, and being paranoid about uptime (and possible lurking bugs in my code), I also wrote some code to add redundancy which switches quote providers when a failure occurs.  I did this on 2 levels… switching between the new and old quote service (these were written as providers using the factory pattern), and also switching between my new services (the same service running on 2 different servers).

Since the switching code seemed like a common element, and needed to error-free, it was a good candidate for abstraction.  For illustration, I’ll use multiplication as redundant service.  (By the way,  I didn’t end up using this code). I’ll work backwards from implementation toward the abstract class.

First, the interface for the 2 functions I want to switch between:

    interface Multiplier
    {
        int Multiply(int x, int y);
    }

The 2 functions which implement the interface:

    class SimpleMultiplier : Multiplier
    {
        public int Multiply(int x, int y)
        {
            return x * y;
        }
    }

    class SlowMultiplier : Multiplier
    {
        public int Multiply(int x, int y)
        {
            int output = 0;
            for (int i = 0; i < x; i++)
            {
                output += y;
            }
            return output;
        }
    }

Now here is the code for FailoverMultiplier.  I’ll show this code before the abstract class to illustrate how the abstract class is used. 

    class FailoverMultiplier : Failover<int, Multiplier>
    {
        public FailoverMultiplier()
        {
            Initialize(“Multiply”);
            members.Add(new SimpleMultiplier());
            members.Add(new SlowMultiplier());
        }
        public int Multiply(int x, int y)
        {
            return RunFailover(x, y);
        }
    }

Now for the abstract Failover class. The interesting part of the code was wrapping the individual Multiply functions within the try/catch of another function, and doing it in an easily reusable way. (fun activity: guess how it’s implemented first). Notice that I also have functionality to optionally prefer the 1st member, and revert back to it after a certain amount of time.

    abstract class Failover<TReturns, TBase>
    {
        protected object lockObject = new object();
        protected int memberIndex = 0;
        protected List<TBase> members = new List<TBase>();
        protected bool preferFirst = false;
        protected DateTime primaryFailTime = DateTime.MinValue;
        private System.Reflection.MethodInfo method;

        protected void Initialize(string functionName)
        {
            Type t = typeof(TBase);
            method = t.GetMethod(functionName);
        }

        protected TReturns RunFailover(params object[] parameters)
        {
            int iterations = 0;
            bool failedState = true;
            TReturns output = default(TReturns);

            if (members.Count == 0)
                throw new Exception(“members list is empty”);
            if (method == null)
                throw new Exception(“‘method’ was not initialized”);

            lock (lockObject)
            {
                do
                {
                    iterations++;
                    try
                    {
                        output = (TReturns)method.Invoke(ActiveMember, parameters);
                        failedState = false;
                    }
                    catch
                    {
                        // do logging
                    }

                    if (failedState)
                    {
                        if (memberIndex == 0)
                            primaryFailTime = DateTime.Now;
                        memberIndex = (memberIndex + 1) % members.Count;
                    }
                } while (failedState && iterations < members.Count);

                return output;
            }
        }

        protected TBase ActiveMember
        {
            get
            {
                if (preferFirst && DateTime.Now.Subtract(primaryFailTime).Hours >= 1)
                {
                    memberIndex = 0;
                }
                return members[memberIndex];
            }
        }
    }

An earlier version of this class required the user to define a function in the FailoverMultiplier class which was to to be called by the abstract class’s function “RunFailover”.  This is necessary if you don’t use reflection or if you need more performance. In my tests, it took 7 seconds to do 1M iterations with the invoke, but .02 seconds to call the function directly.

Posted in Uncategorized | Leave a Comment »

Async postbacks are blocking other postbacks!

Posted by noah on June 25, 2008

This problem took over a week to figure out (ie, run the right google query)

When you create an updatepanel (or any other xmlhttprequest) that takes a long time, then any other postbacks are blocked until the 1st postback is completed… in some cases.  For example, you have a page that delay loads some data, but that data takes 10 seconds to return.  You don’t really care if the data is actually returned before the user leaves the page… it’s just some info like recent quote information.  If the user clicks on any other button on the page, then nothing occurs until the 10 seconds are over.

This problem occurs sometimes.  I noticed that it worked in my sample project, but not in our main codebase.  I whittled down the issue down to global.asax.  If certain event handlers were defined, then the async postback would block.  This made absolutely no sense because it would still occur if the event handler was empty.

Anyways, the reason this was happening is because ASP.net serializes access to the session state.  The 1st postback must finish before the 2nd is processed.   But access to the session state is only serialized if you actually use sessionstate, and I wasn’t using it.  If a handler like Session_Start is defined in global.asax, then a session_id is added to the response as a side effect.  The workaround for this problem is to use EnableSessionState=”False” or “ReadOnly” on the Page directive.

For more information, see http://channel9.msdn.com/forums/TechOff/256322-Strangeness-between-ASPNET-AJAX-and-Globalasax/

Posted in Uncategorized | Leave a Comment »

Referencing ids on web user controls

Posted by noah on June 24, 2008

If you create an ascx file which uses client script to reference a control inside the user control, don’t simply refer the the html control id.  this might cause id name collisions (if you have more than one of the same control on the same page), for example.

To fix this, you need a “namespace” of sorts.  On the referenced id, set runat=”server” as an attribute.  ASP.NET will then assign a new name to the control.  For example, if you control’s name is Foo, it’ll prepend the ascx name to the control’s id like myUserControl1_Foo.

To reference this, use the server function FindControl(string) by passing in the original name (“Foo”) into it.  The new name (“myUserControl1_Foo”) is returned.  Make sure this function is run on the UserControl object, not the Page object, otherwise it’ll look for the id on the Page level.

Posted in Uncategorized | Leave a Comment »