Like everybody else, I find more and more ruby based tools in my environment. The two applications that see the more use on my servers are puppet and its dashboard. I recently moved to puppet 2.7 and started to see deprecation warning about changes in the way variable scope works. Little sidenote here : I still have not realized how to inherit from a parameterized class nor how to refer to a node scoped variable. Without these features, I am afraid I can’t migrate.
One of the things you realize when using puppet, and especially when you are doing a lot of things with it, is how slow it is. Compiling the catalog takes about 5 seconds per run, and applying it around 20 seconds on the most complex configurations. This is alright when it is happening in the background, but it makes me want to rip the keyboard apart when testing recipes.
Anyway, not so long ago testing frameworks for puppet were released. Testing my changes on a controlled environment instead of the production servers is of course a much better idea. But the real increase in productivity comes from the fact that only the catalog is computed, and that my desktop is faster than the VMs. I decided to start migrating as much of my classes and templates to the new scoping system that way.
I figured, after reading several pieces on how you should never use the packaged version of ruby, but install it from shell scripts downloaded from some guy’s web page, to exactly do that. It is possible on my desktop, but is of course out of question on production servers.
So I figured I would test all those nifty ruby versions. I was not impressed.
I wrote a test set for the ruby 1.8 that comes with my lucid distro. There are about 40 rspec “examples”, all of them being tests on how templates were applied to configuration files. All the tests are OK with ruby 1.8, and take about a minute to complete. Yes, this is horribly slow.
With ruby 1.9, some of the tests did not pass. I previously had hacked the testing framework so that it would provide me with a diff between what was computed and what was expected. While the test was saying the two differed, they seemed identical to my diffing feature. The reason should be obvious to seasoned ruby developers, but wasn’t to me. I however had an insight within minutes : all the failing test cases had accentuated letters in them. Once they were removed it started to work again. It took about 38 seconds to run the tests.
Jruby takes 55 seconds to run the tests, and the first one always fails because of some fork error.
Rubinius just doesn’t run any test. It freezes, without even using CPU.
Ruby EE worked, and took around 40 seconds.
So what do I have here ? A must have application written in a poorly implemented language. I am not supposed to use my packaged ruby if I want any support from the “community”, it runs excruciatingly slowly and takes tons of memory. There is a handful of other implementations of the language that are at best marginally faster, and seem to introduce new classes of bugs. But this is supposed to be production ready.
The worst thing about it is that you can’t control a ruby process memory usage. I end up configuring passenger so that it kills ruby processes as soon as they serve 50 requests.