mirror of mongrel-development@rubyforge.org (inactive)
 help / color / mirror / Atom feed
* teaching Mongrel to inherit sockets (and replace mongrel_cluster)
@ 2009-08-14  1:18 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2009-08-14  1:18 UTC (permalink / raw)
  To: mongrel-development-GrnCvJ7WPxnNLxjTenLetw

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-08-14  1:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-14  1:18 teaching Mongrel to inherit sockets (and replace mongrel_cluster) Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).