Looper is a dead simple Ruby module for daemonizing your code, meant for use with Rails' script/runner. No forking involved, no detaching, simply running a nice healthy loop, but allowing your code to bail out of it, and making it responsive to signals.
You implement a class like "DoSomething" that checks for new message objects and then does something to them. This class will include @Looper@ in order to easily loop, respond to shutdown signals, and it can then be run via script/runner as a daemon.
The loop handles sleeping between runs, and will catch any unhandled exceptions that bubble up and keep on truckin'. Thus, if you want to exit on a particular exception, you've got to rescue it in your code and set @@run@ to @false@.
Here's an example usage:
require 'looper' class DoSomething include Looper attr_accessor :run def initialize(config) @run = true # do config stuff, etc... @sleep = config[:sleep].nil? ? 60 : config[:sleep] end # initialize def run loopme(@sleep) do begin # this is where the meat of your code goes... messages = twitter.direct_messages({:since => since.strftime("%a, %d %b %Y %H:%M:%S %Z")}) rescue Twitter::EpicFailure => e puts "bailing out, dude!" # set run to false to put the kabosh on the next run @run = false end end end end # and here's how we kick it off: DoSomething.new( { :sleep => 10 } ).run
Now we can just kick that off any way we like and background the process, but we tend to use it with script/runner in our Rails environments to have access to our models and such. It boils down to:
@$ nohup script/runner -e RAILS_ENV /path/to/DoSomething.rb@
And then looking up the PID by matching on /path/to/DoSomething.rb via grep and use kill to send the term signal.