Skip to content

Instantly share code, notes, and snippets.

@telent
Created March 30, 2011 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save telent/894392 to your computer and use it in GitHub Desktop.
Save telent/894392 to your computer and use it in GitHub Desktop.
for khaase
#!/usr/bin/ruby
require "rticulate-env"
require "sequel"
require "memcache"
require 'pp'
url=URI.parse(Env['rackurl'])
start_port=url.port;
rack_workers=Env['rack_workers'] || 3;
# this trick from http://stackoverflow.com/questions/42566/getting-the-hostname-or-ip-in-ruby-on-rails
#
local_addr=UDPSocket.open {|s| s.connect('10.0.0.1',1); s.addr.last }
if pid=Env['pidfile'] then
File.open(pid,"w") do |f|
f.print "#{Process.pid}\n"
end
end
syslog=IO.popen("logger -t 'rticulate' -p local1.info","w")
syslog.sync=true
def new_child(host,port,syslog)
Kernel.fork do
Object.const_set "CACHE", MemCache.new(Env['memcached'])
Object.const_set "DB", Sequel.connect(Env['database'])
require "rticulate"
require "app/rack-app"
$stdout.reopen(syslog)
$stderr.reopen(syslog)
$stdin.reopen("/dev/null")
DB << "insert into varnish_backends (address) values ('#{host}:#{port}');"
DB << "notify varnish;"
# This needs to be a signal that thin/eventmachine doesn't steal
# the handling of (TERM and INT are apparently no good). Seems a
# reasonable assumption that we won't get a real SIGWINCH after
# closing std*
Signal.trap("WINCH") do
warn "Terminating #{$$}"
DB << "delete from varnish_backends where address='#{host}:#{port}';"
exit 0
end
Rack::Handler::Thin.run(Rticulate.rack_app,
:Host=>host, :Port=>port) do |s|
warn s
end
end
end
def kill_kids(ports)
ports.keys.each do |pid|
Process.kill("WINCH",pid)
end
end
respawn=true
ports={}
rack_workers.times do |i|
kid=new_child(local_addr,start_port+i,syslog)
ports[kid]=start_port+i
sleep 1.5 # avoid thrashing quite as monstrously
end
warn "$0 starting with #{rack_workers} workers: pids "+ports.inspect
Signal.trap("TERM") do
warn "Terminating children"
respawn=false
kill_kids ports
end
Signal.trap("HUP") do
warn "Restarting children"
kill_kids ports
end
until ports.empty?
died=Process.wait
warn "Worker #{died} died"
port= ports[died]
ports.delete(died)
if respawn then
ports[new_child(local_addr,port,syslog)]=port
end
end
pid and File.delete pid
@telent
Copy link
Author

telent commented May 20, 2011

An much more useful version of this can be found at https://github.com/telent/thin-prefork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment