Support running thin under daemontools/runit
Reported by Jos Backus | February 12th, 2008 @ 04:51 PM | in Ruby 1.9
It would be great to be able to run thin under a service manager such a daemontools/runit/launchd/AIX's SRC. The advantages of such an approach are:
- Unified service control interface.
- No use of pidfiles or process table scanning, both of which are brittle (stale pidfiles, pidfile/directory ownerships, issues, process name matching, ps output portability).
- Direct notification (SIGCHLD, waitpid()) instead of polling.
- Automated process restart capability, a la init.
To make thin play nice with this setup, thin should not background itself and instead wait for any children it forks (and restart them if they die, or alternatively exit so that the service manager can restart the cluster. This is similar to how Apache manages its worker children.
A stripped version of the run method in the swiftiply_mongrel_rails script is shown below to demonstrate the general pattern. In the example the manager doesn't bother to restart any children (hence the call to Process.waitall) but modifying it so that it would restart any dead children so that number_of_children are kept running at all times should not be hard. (One would fix the main loop to start processes while current_processes < wanted_processes and use Process.wait instead of Process.waitall at the bottom so that the loop is reentered after each child dies.)
Sample code:
def self.run
args = [ ... ]
children = []
number_of_children.times do |i|
r, w = IO.pipe
cid = fork
unless cid # child
w.close
Thread.new {
begin
r.read # basically blocks until the parent disappears
ensure
STDERR.puts "pid #{Process.pid}: parent died... exiting!"
Kernel.exit
end
}
Mongrel::Runner.new.run(args) # never returns
exit
else
r.close
children << cid
end
end
$stderr.puts "waiting for children: #{children.join(' ')}"
Process.waitall
$stderr.puts "all children exited."
end
Comments and changes to this ticket
-
macournoyer February 13th, 2008 @ 02:26 PM
- → Milestone changed from to Ruby 1.9
- → State changed from new to open
I'll try to prototype that this weekend.
Want concerns me is the extra memory required to run a master process. An empty Ruby VM can use 80 MB on some system.
But recent fixes in Ruby 1.9 GC improve mem usage w/ fork, see: http://thin.lighthouseapp.com/pr...
So it might be a good feature for 1.9
-

Jos Backus February 13th, 2008 @ 02:40 PM
Thank you. Let me know if there's anything I can do to help.
-
Geoffrey Grosenbach November 1st, 2008 @ 04:50 PM
- → Tag changed from to cluster daemon
In the meantime, see Steve Purcell's rails-runit project, which makes this possible:
http://github.com/purcell/rails-...
I'm using it for a few thin apps and it works very well (but requires a bit of setup with runit and a non-root user to run your thin apps).
Please Login or create a free account to add a new comment.
You can update this ticket by sending an email to from your email client. (help)
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
