Deployment readiness

Deployment readiness

Have you ever seen this development cycle?

  1. Install new build
  2. App doesn’t start, doesn’t log any error why
  3. Go back to source code and add improved logging
  4. Install new build
  5. Read logs
  6. Fix the actual problem (usually some stupid configuration thing)
  7. Repeat steps 1-6 until all bugs are gone

Was it because of your code, or someone else’s? This sort of cycle is time consuming, frustrating, stressful, and makes you look helpless (or like a cowboy) in front of project managers and support staff.

If your app can’t produce logs your infrastructure staff can understand, then your app is not even close to production-readiness. If it doesn’t log clear errors, how can anyone hope to deploy and support it?

Stick to the paradigm (even if it sucks)

Stick to the paradigm (even if it sucks)

Today I had the pleasure of fixing a bug in an unashamedly-procedural ASP.NET application, comprised almost entirely of static methods with anywhere from 5-20 parameters each (yuck yuck yuck).

After locating the bug and devising a fix, I hit a wall. I needed some additional information that wasn’t in scope. There were three places I could get it from:

  • The database
  • Form variables
  • The query string

The problem was knowing which to choose, because it depended on the lifecycle of the page — is it the first hit, a reopened item, or a post back? Of course that information wasn’t in scope either.

As I contemplated how to figure the state of the page using HttpContext.Current, my spidey sense told me to stop and reconsider.

Let’s go right back to basics. How did we use to manage this problem in procedural languages like C? There is a simple rule — always pass everything you need into the function. Global variables and hidden state may be convenient in the short-term, but only serve to confuse later on.

To fix the problem, I had to forget about “this page” as an object instance. I had to forget about private class state. I had to forget that C# was an object-oriented language. Those concepts were totally incompatible with this procedural code base, and any implementation would likely result in a big mess.

In fact, it turns out to avoid a DRY violation working out the page state again, and adding hidden dependencies on HttpContext, the most elegant solution was simply to add an extra parameter to every method in the stack. So wrong from a OO/.NET standpoint, but so right for procedural paradigm in place.

SQL Notifications: not very practical for large data sets

SQL Notifications: not very practical for large data sets

I ran into an interesting problem today with command-based SQL Notifications. We’ve recently introduced SysCache2 on a project as NHibernate’s level 2 cache provider, because of it’s ability to invalidate regions when underlying data changes, and I already wrote about some issues we had with it. Unfortunately we hit another road block today, this time with the queries for notification themselves.

Here’s the offending config:

<syscache2>    <cacheRegion name="Tasks" relativeExpiration="9999999">        <dependencies>          <commands>              <add command="SELECT ID FROM Task" connectionName="Xyz" />              <add command="SELECT ID FROM TaskUser" connectionName="Xyz" />              ...          </commands>      </dependencies>    </cacheRegion></syscache2>

Can you spot the bug here that will result in an unhandled exception in ISession.Get()?

Nope? Neither could I for most of this afternoon.

Query for notification timeout errors

The problem is that the Task and TaskUser tables have four and six million rows respectively. SELECT ID from TaskUser takes over 90 seconds to execute. At this speed, by the time we have re-subscribed to the query notification, new data would have already been written by other users.

Depending on your exact scenario, you have several options:

  1. Refactor the database schema to remove rows from these tables that aren’t likely to change.
  2. Accept the slow query subscription.
  3. Enable caching, but ignore changes from these tables.
  4. Limit the command to only cover rows that are likely to change, e.g. SELECT ID FROM Task WHERE YEAR(DueDate) = 2009.
  5. Disable level 2 cache for these entities entirely.

Accepting the slow query subscription only works if you have very infrequent writes to the table, where it is worth caching rows for a long time.

For us, the high frequency of writes to these tables means that we would be invalidating the cache region all the time, and limited sharing of data between users doesn’t give much benefit in caching. Also blocking a HTTP request thread for 90 seconds is not feasible. So we chose the last option and now don’t bother caching these tables at all.

By the way, while working on this problem, I submitted my first patch to NH Contrib that adds a commandTimeout setting to SysCache2.

Duct-tape programmers ship… once

Duct-tape programmers ship… once

I read an interesting article today full of praise for duct-tape programmers, a breed of developers who are smart enough to get away without unit tests, and ship code early by using duct-tape style programming techniques.

Duct-tape programmers are considered great because they help companies take first-mover advantage, while others waste time developing abstract frameworks and trying to over-engineer everything. Customers and project managers love duct-tape programmers because they get the job done fast.

I see duct-tape programmers in a different way:

Of course you need to ship products fast to beat your competition. But duct-tape isn’t a sustainable way to build software, unless you have the luxury of never having to touch the code again (one-off console games come to mind here). Otherwise, maintenance costs from brittle code will soon come back to bite and affect your ability to ship version 2.0 in time.

Our challenge is to find a balance in the middle where we aim high, but have an architecture flexible enough to allow duct-tape-style compromises in a clean and isolated fashion when required.

I can’t decide if this is an application service, or a domain service!

I can’t decide if this is an application service, or a domain service!

Deciding whether a service belongs in the domain or service layer can be a very tough question.

I think it’s important to remember that, just because a class:

  • Deals exclusively with objects in the domain model
  • Is called in turn by other application services
  • Has no dependencies on other non-domain services

…does not make it a domain service.

Try not thinking of it as the domain layer, but as the domain model. The domain model is a very strict abstraction of the business; domain layer is just a tier in your app where the model resides. It’s a small change of words but a big difference in perspective.

Is your service actually part of the domain model, or just manipulating it?

IUnityContainerAccessor must use a static container instance

IUnityContainerAccessor must use a static container instance

I found an interesting problem this morning when my ASP.NET MVC application mysteriously broke after adding an HttpModule in the web.config. Here’s the problem code:

public class MvcApplication : HttpApplication, IUnityContainerAccessor{    IUnityContainer container;        public IUnityContainer Container    {        get { return container; }    }    public void Application_Start()    {        this.container = new UnityContainer();        // this.container.RegisterTypes etc    }

The container was being configured fine in Application_Start, but then UnityControllerFactory would throw “The container seems to be unavailable in your HttpApplication subclass” exceptions every time you tried to load a page — this.container was somehow null again.

After doing a little digging and finding this article where someone had the same problem with Winsdor, it seems ASP.NET will create multiple HttpApplication instances when parallel requests are received. However, Application_Start only gets called once, so anything you would like to share between multiple instances (e.g. your IoC container) must be static:

public class MvcApplication : HttpApplication, IUnityContainerAccessor{    static IUnityContainer container; // good    IUnityContainer container; // bad, not shared between HttpApplication instances        public IUnityContainer Container    {        get { return container; }    }