Wednesday, September 10, 2014


In my last whiny post I stated that we tend to solve the symptoms and not the root problem, Jaco Joubert challenged me to define what the real problem is; fair enough.

The root problem is that we write fragile software that stumbles when there are unexpected changes in the environment. The simplest solution to this problem is to lash down the environment. If the environment does not move, then our software will not fall over. This is exactly what Docker does. And if a software system consisted of a single delivery then the cheapest solution is likely the best solution. 

However. My unease is caused by two fundamental issues: 

* First, we will write the same amount of software in the next 7 years as all the software written since the big bang. 
* Second, successful software systems tend to live a long time and evolve continuously. 

In such a gyrating environment the only thing constant is change. Change that Docker will allow us to largely ignore because we create a warm nest where this bad outside world does not intrude. Sloppy programming like hard coded path names and making other assumptions about our environment will not be punished. Initially this will work perfectly ok. However, over time your modules will become more and more tied to your unique environment because we have a hard time resisting a short-cut when they see one. These short-cuts will make the modules less and less reusable, which will probably make it easier to double the lines of code in the next 7 years but efficient is different. It will also make it harder to evolve your own environment because a lot of its details will be hardcoded in all the components. Expect another variation on the spaghetti model.

The root of software bugs is almost always a violated assumption in the code, therefore, not having these assumptions is the way to go, even though this can be very hard work. Not only will this reduce bugs, it will also make code more reusable because not-knowing something also reduces constraints between modules. A great way to structure this is to do contract based programming, something which reaches its (current) perfection in the OSGi service model. 

The argument is therefore that the virtual-image model (which Docker just makes more usable) will let sloppy programming go unpunished until the big bang.

Now, the picture is not black and white; I actually feel a bit uncomfortable with such an argument in other places and I clearly see the shorter term advantages of the container model. Maybe jet fighter pilot training provides some insight. Their simulators are running significantly faster than real life. The result is that when the pilots are deployed in a real fight it actually feels a tad boring. This is why during development I want an open world and as much dynamics as possible to capture our team's false assumptions early. However, when the code actually gets deployed to Q&A I want a locked down environment that will be bitwise identical to the image that goes to production.

Ah well, that is why I love this industry, never a dull moment.

Peter Kriens

1 comment:

  1. Thanks for the quick follow-up Peter.

    I fully understand your argument. In my mind, the (short term?) benefits of something like Docker is just so big that it would be really hard to ignore.

    For one, just the fact that I can get a development environment going quickly by just running a pre-baked image saves me a lot of time on development teams.

    Another example is that I can more easily version (required) environment changes with every release. I know there are other solutions out there for this as well, but docker is a pretty good one!

    I guess the question is then how do we prevent sloppy programming and ensure that we create proper re-usable components while still enjoying the benefits of something like docker.
    I might sound a bit negative, but I think we largely failed as an industry to do this up to now.. and I see your argument is that it will only get worse.. I don't think we really know what it takes to develop proper re-usable components, so up to now we haven't really been doing that to a larger extent. The biggest "re-use mechanism" I've seen is basically copying ideas / code and adapting it to your need and create yet another version. Definitely not ideal, but that's at least my experience.

    Interesting problems to solve indeed!