Eric Wong
2009-Aug-14  01:18 UTC
[Mongrel-development] teaching Mongrel to inherit sockets (and replace mongrel_cluster)
This change to Mongrel should be completely harmless for non-UNIX
systems, too (it won''t break (or do) anything).
This minimal change let Mongrels inherit listen sockets from a parent
process, so that parent could be a cluster manager.  This means no more
port juggling with mongrel_cluster!  The entire Mongrel pack will all
share one port.
Only the manager script (see below) itself relies on UNIX-isms (but I
think mongrel_cluster did, too).
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 0619abe..90e99e7 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -91,7 +91,11 @@ module Mongrel
     def initialize(host, port, num_processors=950, throttle=0, timeout=60)
       
       tries = 0
-      @socket = TCPServer.new(host, port) 
+      @socket = if ENV[''LISTEN_FD'']
+        TCPServer.for_fd(ENV[''LISTEN_FD''].to_i)
+      else
+        TCPServer.new(host, port)
+      end
       if defined?(Fcntl::FD_CLOEXEC)
         @socket.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
       end
---
Here''s my initial cut of a mongrel_cluster replacement, it can
definitely be cleaned up and improved upon with real option parsing and
such...
---------------------------------- 8< ----------------------------------
#!/usr/bin/env ruby
require ''socket''
nr_workers = 4
pids = {}
cmd = %w(mongrel_rails start)
server = TCPServer.new(''0.0.0.0'', 3000)
server.listen 1024
ENV[''LISTEN_FD''] = server.fileno.to_s
# pass any signals we receive onto each child process:
%w(TERM INT USR1 USR2).each do |sig|
  trap(sig) do
    pids.keys.each { |pid| Process.kill(sig, pid) rescue nil }
    exit 0 if sig == ''TERM'' || sig == ''INT''
# TERM and INT mean death
  end
end
nr_workers.times { |i| pids[fork { exec *cmd }] = i }
loop do
  pid, status = Process.waitpid2(-1)
  i = pids.delete(pid) or next
  STDERR.puts "reaped worker #{i}: #{status}, respawning..."
  pids[fork { exec *cmd }] = i
end
---------------------------------- 8< ----------------------------------
-- 
Eric Wong