Support running thin under daemontools/runit
Reported by Jos Backus | February 12th, 2008 @ 04:53 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 set 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
-
Geoffrey Grosenbach November 1st, 2008 @ 04:50 PM
- Tag set 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 Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป