Practicing safe Ruby, with safely

One of the things that makes daemon-kit such a great project (at least to me), is the built-in “safely” method wraps your code in a loving embrace of error reporting comfort. You could at any point do this:

safely do
  something_dangerous!
end

and your daemon would not die if something blew up. Instead the daemon would happily log the error to file (and possibly Hoptoad) and carry on working.

As part of resurrecting daemon-kit, I’ve extracted this functionality into a new gem called “safely“, available now on Github and Rubygems. At the moment it just supports Hoptoad via the Toadhopper gem, but soon will offer more!

I’ll expand on it in the coming days, and then tend to the daemon-kit fork queue while replacing the daemon-kit version with safely.

daemon-kit 0.1.8 released

I’m proud to announce that daemon-kit has finally made it to 0.1.8.1, almost a year after the last patch release. There has been a lot of changes since the last release, mostly cleanly up and staying with the times (so to speak). Github has an awesome compare view, detailing the historic moment, and I’ll go through it here in some detail as well.

First off I’d like to thank a few people who have quietly and vocally contributed to or promoted daemon-kit. In no particular order, thanks goes to:

The two biggest changes for me has been converting all the generators to use Thor, and using Bundler in the generated daemons. Both of these projects have received some flack, but they both continue to serve me very well and I’m sure they’ll serve daemon-kit well.

The logger got some minor updates, to be more compatible with the standard Ruby logger class. A brand new XMPP generator is included, and it uses Blather for some awesome evented-goodness. Argument handling got fixed up, email exceptions got removed from the project (I might consider implementing them after overhauling the error reporting features of dk). Hoptoad error reporting got upgraded to the use the newer API. The generated rake tasks are more forgiving when rspec/cucumber or other gems are missing. The cron daemon got some love, allowing easier exception logging/notification for when scheduled tasks fail.

I’ll continue chipping away at the project, tidying up loose ends as they are reported, and start developing a proper test suite for everything.

Over the long term I’m hoping to reach the following goals:

  • Always running the eventmachine reactor (think node.rb)
  • Support for more modular daemons, including ‘single-file’ daemons
  • Support for daemons inside Rails projects

Some things will probably get thrown out, like generating configs for god & monit. The more I use chef, the more I realize that those responsibilities lie with the infrastructure management (or devops), and not within the project itself. I’m aware this might cause an upset, however I firmly believe that a lighter and smaller daemon-kit will serve the greater community better.

Thanks for making daemon-kit the number 1 daemonizing project. Please share the love and send feedback, and more importantly use Github issues to log issues, feedback, and wishes.

Looking beyond daemon-kit 0.2

Works Ahead - Singapore Department of Transport

I wrote daemon-kit to solve two big issues with writing daemon processes in Ruby:

  1. Everyone is re-inventing the daemons gem
  2. Individual daemons share a lot common code, apart from the daemonizing bits

As for #1, daemon-kit at first wrapped the daemons gem, and later ripped it out completely as it was difficult to wrap up the worst of the daemons gem properly.

#2 seemed to be a twofold problem that daemon-kit has also addressed with great success. The first was addressing the all too common issues of logging, pid file management, umasks, signal traps, config files, exception handling and other “low-level” issues. Everyone was implementing these things to a limited extent in their daemons and this could cause a lot of frustration when done wrong. The second part was the need, even if undiscovered, for higher level re-use and development speed. Daemon-kit addresses this with some limited generators, making it easy to get going with a cron-style daemon, AMQP & XMPP bots as well as the newest addition, Ruote remote participants.

All this is fine and well, and people seem to like the project. The mailing list is getting some noise, we’re over 200 watchers strong on Github and the IRC channel has some folks popping in to say hi.

However, daemon-kit quickly made me lazy and realize there is a couple of things it can do much better. If you’ve used a generator before, you’ll notice the generated code is very much stuck to that type of daemon. Changing from XMPP to AMQP (for illustrative purposes) would be best accomplished by generating a new project and copying over the lib/ folder only. This sucks.

Another problem is people, myself included, would like to have Sinatra-style daemons (i.e. one file) for smaller tasks. Currently this is not possible at all. Another thing I know people are doing behind my back is generating daemons inside Rails projects, which may or may not work, depending on whether you load Rails’ environment.rb.

So, what happens now?

My thoughts are to implement privilege dropping support and tag a 0.2 release. This gives us a feature complete framework, albeit not as good as it can be. I’ll maintain 0.2 as a stable while undertaking the rewrite. A rewrite? Read on.

I posted to the daemon-kit list a suggestion for stackable daemon environments. I’ve discussed this in IRC with a few folks as well. Jordan Ritter gave me an exceptional breakdown of the dangers of doing something because it is “neat” and I’ve taken his warning to heart. However, I cannot seem to argue against stackable daemon environments, it sounds too good.

The idea is pretty simple. Stack-entries can be compared to Rack applications, with two significant differences. The first is that they will be called only once. They have the opportunity to change the environment in which the final code runs. The second is that they can be called at four different stages of the daemon lifecycle: argument processing, pre-daemonization, post-daemonization and shutdown. This differs from Rack’s single call() method.

The stackable nature also gives the stack members easier ways to set conventions and can dramatically minimize configuration. It paves the way for plugins, sinatra-style daemons, rails-based daemons and easier packaging of distributable daemons, and so much more. Looking at the internals of daemon-kit, it would greatly help simplify the existing code as well as help separate utility classes from stack members.

The more I think about it, the more obvious this becomes, and the more possibilities unfold for the framework. This will definitely make daemon-kit a force to be reckoned with, and hopefully I can persuade other library developers to offload their daemonizing code to daemon-kit, just like rack developers offload their HTTP handling to rack.

DaemonKit Lightning Talk RubyKaigi 2009

Undoubtedly my worst time on stage ever! Ubuntu gave me issues with the projector, so I actually had to leave the stage to go to another conference hall to get the setup working again and run back up to the main hall… Once there, I was a mumbling mess, but made it through without the buzzer beating me.

Presenting a lightning talk at a Japanese conference is surely something else, the audience expects fireworks and the presenters deliver. It was truly an amazing experience, humilation and all, and I’m looking forward to the last day of the conference.