# Tuesday, September 15, 2009

Its amazing how one single line of code and a bad assumption (or misunderstanding) can cause all sorts of strange production issues.

The day started out with static content throwing exceptions that contained our UnitOfWork in the call stack.  My first question was, why on earth is a static resource request hitting our begin unit of work.  Well it turns out that we map all requests through the ASP.NET pipeline because of some nameless .NET document management module.  Unfortunately we generally don’t have wild card mapping enabled for ASP.NET in our dev environment because:

  1. We weren’t aware of the requirement.
  2. There’s no documentation surrounding proper dev environment setup (e.g. script).
  3. Only one dev in our entire organization has ever actively touched this module.

Why is the wildcard mapping a big deal?  Because a single page load will create 10, 20, or more HTTP get requests for static content.  If you have a threading bug in your begin request, they’re much, much more likely to show up with numerous requests. 

The sad truth of the matter is that because our environment we have a lot of NHibernate session factories, which is not normal for most applications. All of these session factories need to be configured and were using Fluent NHibernate to do so.  FNH is a great tool and makes configuration so much easier for us devs, but the fact remains FNH is not thread safe.

Seems easy enough, put a lock around the FNH stuff.  Well, we did, but the locker class was not static, we were relying on AutoFac to ensure that our NHibernate session factory class (the class with the lock) was a singleton.  Not too hard since AutoFac defaults to singleton.

Here’s the mistake.  ASP.NET creates not one, but many HttpApplication instances for each app domain.  I was falsely under the assumption is only ever created one, maybe two, but only ever kept one around.  Our AutoFac registration was setup in the Global instance constructor, so each app instance was getting its own container instance.  Can you guess why this is bad?

Each request had its own NHibernate configuration class with its own instance lock, thus multiple threads were entering into the critical section at the same time since they couldn’t see each other.  Lots of weirdness ensued.  We saw all sorts of the strange Nhibernate and FNH errors, things like property “XYZ” doesn’t exist on class “ABC".  Odd stuff that definitely smelt of threading.

I was starting to think SELECT was broken (e.g. AutoFac), but soon realized the errors of my ways with a simple Debug.Assert. Yep, multiple container, produce multiple “singletons”. 

WTF
Tuesday, September 15, 2009 1:54:46 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, April 04, 2008

I was using ReSharper's Unit Test Runner today, and all was good until it suddenly stopped working with no error message.  You would run the tests, it would spin for a second, then show no results - everything was grey.  Try to run test in debug mode, same thing, no break points ever get hit.

This was very frustrating since I had no indication of what the problem was.  I ended up throwing the test DLL into NUnit itself, which showed a nice error dialog "Assembly Not Loaded" which indicated there was an error in the test project's app.config.  Argh!

At least it gave me an excuse to download and install NUnit 2.4.7.  Apparently they added rowtest support?  I like the sound of that.

WTF
Friday, April 04, 2008 10:42:55 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 20, 2008

You might immediately suspect a C# class is breaking the single responsibility principle when you discover upon opening it that the entire first page is nothing but using statements.  38 in all, and that's after using Re# to remove the unused ones.

Can you guess what kind of class this is?

If you guessed a code behind to a winform dialog then you guessed right.

.NET | WTF
Thursday, March 20, 2008 10:27:40 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, January 10, 2008

Developed data access class containing over 5,000 lines of code and over 100 methods

WTF
Thursday, January 10, 2008 8:28:45 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, October 29, 2007

I opened up another tab to Udi Dahan's blog, at which point my PC came to a screeching halt.  After finally getting the task manager open I noticed FireFox was using 1.5GB of RAM.  Wow!  IE never uses that much memory - in fact IE usually crashes well before it ever gets that much memory consumed.  Here's a look at my memory usage after I killed FireFox, note the huge drop in the Physical Memory Usage History (blue line).

FireFoxMemUsage

WTF
Monday, October 29, 2007 5:44:12 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 06, 2007
This is almost blasphemous, but I'm disappointed with JetBrains right now.  If you don't know they make the excellent Re# plugin for Visual Studio.  I'm disappointed because my trial license of Re# 3.0 ran out and I had to go purchase the software.  I procrastinated a while but I wasn't worried about it because you can  buy it online and enter a license code to activate it.  That's what I thought until I didn't see my license email immediately show up.  After reading their website help I found this:

Delivery Information

JetBrains products are available via electronic delivery only. The product license details will be e-mailed to you within 2 business days of receipt of your order.

What?!  How can this happen in this day and age, especially from a company that makes kick-ass software? This means there must be a manual process in there somewhere, so now I'm stuck using regular Visual Studio all day.  I feel like I'm programming twice as slow today.

WTF
Monday, August 06, 2007 5:56:36 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, June 26, 2007
I'm sure we've all seen this one at some point.  A comment that's less elegant than the code:

// these actions only occur if this is NOT a postback
if (!IsPostBack)
{
    if ((strDiscountCode != null) && (strDiscountCode != String.Empty))

...


WTF
Tuesday, June 26, 2007 9:08:43 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, June 21, 2007

How not to handle storing database connection string information

// if we don't find the connection string in session state, assume that we
// need to initialize all session variables
if (this.Session["connect_comersus"] == null)
{
    this.Session.Add("connect_comersus", (string) strConnect);
}

How not to get the current assembly version for a web app, here's the relevant appSetting:

<add key="dll_path" value="\\CorpWebServer\WebAppROOT$\Secure\bin\Company.CorpSite.Secure.dll" />

Here's the code that reads the version:

        private string GetBuildText()
        {
            string strPath = null,
                strVersion = null,
                strDate = null,
                strReturn = null;
            FileInfo fiMain = null;
            Assembly objMain = null;

            strPath = ConfigurationSettings.AppSettings["dll_path"];
            fiMain = new FileInfo(strPath);
            if (fiMain.Exists)
            {
                objMain = Assembly.LoadFrom(strPath);

                strDate = fiMain.LastWriteTime.ToString("ddMMMyyy HH:mm");
                strVersion = objMain.GetName().Version.ToString();

                strReturn = strVersion + " &diams; " + strDate;
            }
            else strReturn = String.Empty;

            return strReturn;
        }

There are many more, but that's enough for right now.




WTF
Thursday, June 21, 2007 9:25:18 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, June 20, 2007

The “empire” cares more about political prestige than it cares or knows about technology.  The empire is setup structurally to create infighting and to stifle team work.  This is done to create the illusion of potential progress but it really just ends with a circle of finger pointing.

The empire is clearly run by a bunch of bureaucrats whose aim is to pacify the masses with bloated software factories.  Why software factories, complicated frameworks, and RAD generated goo?

  1. Claimed reuse.  By spending a ton of money on a platform we ensure support and reduce costs by reducing redundancy.  In reality we end up with an overpriced and bloated platform that only gets us 80% of what we need.
  2. Feature bullet points.  This supposedly makes the customer feel warm and fuzzy because there are a lot of out of the box features.  In reality most of these bells and whistles will never be used; and to top it these features lock us in to the platform.
  3. It makes the empire look professional.  In reality the empire chose the software factory because they really know nothing about software development.  By having a bunch of useless code on the table it gives them something to talk about and hide behind in their endless meetings.
  4. Mort can understand it.  Maybe Mort can run the wizard to generate more goo, but what happens when you run into some nasty threading bug on your web server?  Do you just start over? 

The empire assumes the worst of developers; they believe developers are a bunch of lazy interchangeable Morts or parts.  They pander to the lowest common denominator because of high turn over and the inability to attract real engineers who are not only good, but passionate about software development. 

In effect, the empire doesn’t know the difference between a programming God and a Mort.  Even if a God did manage to sneak into their ranks they would surely be stifled by the systems the empire has put into place to protect itself.  The empire stays safe by locking everything down so that nothing moves; the theme here is to avoid risk at all costs (option 1, do nothing).

Therein lies the root cause of evil within the empire, they almost always choose to do nothing because it’s safer, but it’s safer because their alternative to “do nothing” is the “all or nothing” approach.  They choose all or nothing largely because their process and their software is incapable of adapting, once it has shipped its set in stone. 

The calcified software is only mimicking the inflexible process laid down by the empire’s inner PM sanctum*.  Besides the PM’s living and breathing waterfall, the real tragedy is the funding model.  The funding model wants the exact cost of the completed system up front, well before any design, let alone coding has started.  This funding model tied to an arbitrary deadline gets the customer some software, but as it often turns out its not the software the customer needs or wants.  The end goal is not about satisfying the customer or improving the process, the end goal is to stay within budget and to check all the boxes.

With the project complete (according to the Gantt chart) the empire moves on to yet another project to replace the new legacy system just completed, and the circle of software creationalism start anew.

 

* Interestingly enough the empire’s PM methodology is called Atlas after the great iterative submarine ballistic missile program from the late 1950’s and early 1960’s.  The real interesting part of this is that the empire’s methodology is pure waterfall, and is nothing like the Atlas missile program.  In fact some of the stupid PERT calculations used during that program were bogus and only used to satisfy the bureaucrats.

Other | WTF
Wednesday, June 20, 2007 7:08:27 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, May 24, 2007
I had forgotten how much I hate dealing with web projects in Visual Studio 2003, until today.  I went to open up one of our companies VS 2003 web projects and didn't have a virtual directory configured before hand, so when it tried to open it complained it couldn't find the path to the csproj file.  OK, no big deal, open up inetmgr and create a virtual directory.  Well that was a good though, except I entered the incorrect path for the virtual directory.  Try again, change the virtual directory to the correct path and try an open the project again.  No good, I get this error now, "Unable to get the project file from the web server."  What the?

The fix: delete *.* from c:\documents and settings\sneal\VSWebCache.

Thursday, May 24, 2007 6:01:56 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, May 17, 2007
My little demo/test application that I monkey around with from time to time got a major revamp today.  Nothing fun or exciting, just a lot of infrastructure cleanup that I've been needing to do for some time.  I was hoping this would only take me an hour, but in reality it took me 3 times longer than that.  All I needed to do was:
  1. Upgrade NHibernate from 1.2 beta3 to NHibernate 1.2 GA.
  2. Separate out my shared core library into a separate folder/solution structure.
  3. Stop using GAC'd Castle and NUnit assemblies and use a local libs folder to facilitate building on a clean box.
Nothing fancy, but I ran into some serious issues with log4net.  You would think that because most open source projects use log4net, integration of multiple open source products that use log4net would be a breeze right?  Well, Castle RC2 uses log4net 1.2.9.0 while the latest NHibernate release uses log4net 1.2.10.0.  That seems fine, just add an assembly binding redirect to have castle using the newer log4net version right?  Well that's fine until you realize that the log4net team unexplicablly changed their signed key between those releases, which means you can't use a binding redirect.  Oops, I doubt the log4net team intended that to happen.

To get around this version mismatch I ended having to grab the latest code from the Castle subversion repository which included log4net 1.2.10.0 and build my own assemblies that would play nicely with  NHibernate.

The moral of this story is don't change your keys between versions if they're binary compatiable/incremental updates.  Especially for something so commonly shared as log4net.

.NET | WTF
Thursday, May 17, 2007 10:22:46 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 27, 2007
I have finally come to the realization that my mindset, beliefs, programming methodology, and above all my spirit are incompatable with my current employer.  I need to work for IT company again.

WTF
Tuesday, March 27, 2007 9:59:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, March 10, 2007
Right now I'm refactoring an ASP.NET 1.1 application that another team member wrote not too long ago.  When I took it over there were 6 unit tests (4 working ones), but really they weren't true unit tests because the code that went into production was never getting tested.  They weren't really testing anything except for the special case code that only ran when under test.

if (m_testingData)
{
   serviceResults = m_testingData;
}
else
{
   RequestorDataService ds = new RequestorDataService(m_url);
   ds.Message = CreateSOAPRequest();
   ds.Submit();
   serviceResults = ds.GetResults();
}

Does anyone see a problem with the above code fragment?  Some IoC love would go a long way here.

Testing | WTF
Saturday, March 10, 2007 8:55:23 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Wednesday, October 11, 2006
I came across this snippet of javascript in one of our apps...

if(i == 0 || i == 2 || i == 3 || dirty == ''){
//had to do this weird workaround as i!=0 was not working
}

WTF
Wednesday, October 11, 2006 6:00:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |