A long time ago, on something less powerful than my current wristwatch, I read an article by Jeff Atwood titled Falling Into The Pit of Success. And because of the type of person that Jeff seems to be (I only know him from the internet…) two things are true:

  • The article is still available on his web-site, in it’s original form
  • The article is still as true and relevant today as it was all those years ago

Grail Knight - Copyright Lucasfilm

And yet the number of people who are aware of the pit of success is tiny!

In my instance I was talking with one of my colleagues, we were looking at the performance of a service, and worked out that some caching would help enormously. This time the monitoring guided us down the path of nHibernate Level 2 Caching.

Context switch

But before we carry on a bit of context: It happens that we work with nHibernate a lot, and have dug our own pit of success for nHibernate. We have an in-house package that the developer installs, they add a small amount of (reasonably well documented) code and configuration to the project and get nHibernate talking to their database. Magic!

Well actually it isn’t. It’s convention over configuration. By spending a bit of time to work out what we did most of the time and codifying this as a set of conventions (which are very close to the Fluent nHibernate conventions), I have been able to tell my team “Do databasing in this way, put in this config and this bit of code and it will all work!”. And it does. Which is nice.

Story time

But going back to my story, we had never dealt with L2 cache before. I know! Weird right? My colleague did some hacking around in code, and worked out how to make the whole thing a convention, and she took me through it. When we finished I noticed that one of the table in the database was, for obscure but good reasons, not following the conventions and asked about.

Colleague: [Reasons why the id needed to be generated by SQL Server, not nhilo]

Me: Ok, cool, and I see you found the way to do it easily enough?

Colleague: Yeah, and I was wondering about making it a convention, like the Level 2 stuff

Me: Ok, why’s that?

Colleague: It would be really easy, and then next time someone needs to do it they don’t need to go through this palaver

Me: It was that hard?

Colleague: Not really, but it needed more code than I liked

Me: Ok

Colleague: And as I said, making it a convention isn’t that hard

Me: I’m pretty sure that you’re right that making it a convention would be easy, but I don’t think we should do it

Colleague: Why?

© Can Stock Photo / corachaos

Thought experiment(!)

And this is an interesting question. So let’s do a thought experiment. We add the ability to use generated id’s to the set of nHibernate conventions, and it quickly becomes known that now there are two Id stategies:

  • Generated Id’s (assigned by SQL Server, usually through an IDENTITY() field)
  • HiLo where nHibernate manages the Id’s of records, but needs a populated nhilo table

You are the developer on the next project and need a new table with a new identity column. Which strategy are you going to choose? Yup, I’m choosing IDENTITY() as well, because it’s easier.

Your application/service goes into production and has performance issues, and we find out that these are because of the inserts, which nHibernate is having to do sequentially (whilst getting the record id’s from SQL Server), because it doesn’t control the id column anymore. And the pit of success is now the pit of despair.

Escape ladders, ponds and guided busways

So what to do about this? Well actually I already did, when the configuration library and conventions were built I put in some very specific escape ladders precisely for these kind of scenarios. The escape ladders are not widely publicised, or used, but they aren’t hidden away either. And as my colleague demonstrated they work.

And we have successfully taken this strategy and applied it to several other areas. For our Dependency Injection needs we use Autofac, and we have a bunch of conventions built up around this, including around slightly more complicated things like decorator registration, that mean for my team these are no longer advanced topics, and we can harness their power easily and repeatedly.

And finally how is the pit of success not just for developers? The point is there in Jeff’s orignal post. You can take the principal and apply it to pretty much anything. And any product or process that has had some time and thought lavished upon it probably also lives in (or very near) the pit of success.

So in truth the pit of success should be less a pit, and more a shallow pond, or perhaps a guided busway. But then I wouldn’t be using pictures of Indiana Jones…