aboutsummaryrefslogtreecommitdiffstats
path: root/railties/dispatches/gateway.cgi
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-07-06 04:29:18 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-07-06 04:29:18 +0000
commit707106f347fada1ac9a7c9e2da7e6d2342f8441d (patch)
tree41f972702ec8cd2e47983120618bbb9d89c420f8 /railties/dispatches/gateway.cgi
parent31702951365c26f930a5f39698cb51309e111e98 (diff)
downloadrails-707106f347fada1ac9a7c9e2da7e6d2342f8441d.tar.gz
rails-707106f347fada1ac9a7c9e2da7e6d2342f8441d.tar.bz2
rails-707106f347fada1ac9a7c9e2da7e6d2342f8441d.zip
Added fixed gateway script [Nicholas Seckar]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1721 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/dispatches/gateway.cgi')
-rw-r--r--railties/dispatches/gateway.cgi113
1 files changed, 76 insertions, 37 deletions
diff --git a/railties/dispatches/gateway.cgi b/railties/dispatches/gateway.cgi
index d9f0c17846..d21bf0991a 100644
--- a/railties/dispatches/gateway.cgi
+++ b/railties/dispatches/gateway.cgi
@@ -1,58 +1,97 @@
-#!/usr/bin/ruby
-
-# This is an experimental feature for getting high-speed CGI by using a long-running, DRb-backed server in the background
+#!/usr/local/bin/ruby
require 'drb'
-require 'cgi'
-require 'rbconfig'
-VERBOSE = false
+# This file includes an experimental gateway CGI implementation. It will work
+# only on platforms which support both fork and sockets.
+#
+# To enable it edit public/.htaccess and replace dispatch.cgi with gateway.cgi.
+#
+# Next, create the directory log/drb_gateway and grant the apache user rw access
+# to said directory.
+#
+# On the next request to your server, the gateway tracker should start up, along
+# with a few listener processes. This setup should provide you with much better
+# speeds than dispatch.cgi.
+#
+# Keep in mind that the first request made to the server will be slow, as the
+# tracker and listeners will have to load. Also, the tracker and listeners will
+# shutdown after a period if inactivity. You can set this value below -- the
+# default is 90 seconds.
+
+TrackerSocket = File.expand_path(File.join(File.dirname(__FILE__), '../log/drb_gateway/tracker.sock'))
+DieAfter = 90 # Seconds
+Listeners = 3
-AppName = File.split(File.expand_path(File.join(__FILE__, '..'))).last
-SocketPath = File.expand_path(File.join(File.dirname(__FILE__), '../log/drb_gateway.sock'))
-ConnectionUri = "drbunix:#{SocketPath}"
-attempted_start = false
+def message(s)
+ $stderr.puts "gateway.cgi: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
+end
-def start_tracker
- tracker_path = File.join(File.dirname(__FILE__), '../script/tracker')
+def listener_socket(number)
+ File.expand_path(File.join(File.dirname(__FILE__), "../log/drb_gateway/listener_#{number}.sock"))
+end
+
+unless File.exists? TrackerSocket
+ message "Starting tracker and #{Listeners} listeners"
fork do
Process.setsid
STDIN.reopen "/dev/null"
STDOUT.reopen "/dev/null", "a"
-
- exec(File.join(Config::CONFIG['bin_dir'], Config::CONFIG['RUBY_SO_NAME']), tracker_path, 'start', ConnectionUri)
+
+ root = File.expand_path(File.dirname(__FILE__) + '/..')
+
+ message "starting tracker"
+ fork do
+ ARGV.clear
+ ARGV << TrackerSocket << Listeners.to_s << DieAfter.to_s
+ load File.join(root, 'script', 'tracker')
+ end
+
+ message "starting listeners"
+ require File.join(root, 'config/environment.rb')
+ Listeners.times do |number|
+ fork do
+ ARGV.clear
+ ARGV << listener_socket(number) << DieAfter.to_s
+ load File.join(root, 'script', 'listener')
+ end
+ end
end
-
- $stderr.puts "dispatch: waiting for tracker to start..." if VERBOSE
+
+ message "waiting for tracker and listener to arise..."
+ ready = false
10.times do
sleep 0.5
- return if File.exists? SocketPath
+ break if (ready = File.exists?(TrackerSocket) && File.exists?(listener_socket(0)))
end
-
- $stderr.puts "Can't start tracker!!! Dropping request!"
- Kernel.exit 1
-end
-unless File.exists?(SocketPath)
- $stderr.puts "tracker not running: starting it..." if VERBOSE
- start_tracker
+ if ready
+ message "tracker and listener are ready"
+ else
+ message "Waited 5 seconds, listener and tracker not ready... dropping request"
+ Kernel.exit 1
+ end
end
-$stderr.puts "dispatch: attempting to contact tracker..." if VERBOSE
-tracker = DRbObject.new_with_uri(ConnectionUri)
-tracker.ping # Test connection
+DRb.start_service
-$stdout.extend DRbUndumped
-$stdin.extend DRbUndumped
-
-DRb.start_service "drbunix:", $stdin
-$stderr.puts "dispatch: publishing stdin..." if VERBOSE
+message "connecting to tracker"
+tracker = DRbObject.new_with_uri("drbunix:#{TrackerSocket}")
-$stderr.puts "dispatch: sending request to tracker" if VERBOSE
-puts tracker.process($stdin)
+input = $stdin.read
+$stdin.close
-$stdout.flush
-[$stdin, $stdout].each {|io| io.close}
-$stderr.puts "dispatch: finished..." if VERBOSE
+env = ENV.inspect
+output = nil
+tracker.with_listener do |number|
+ message "connecting to listener #{number}"
+ socket = listener_socket(number)
+ listener = DRbObject.new_with_uri("drbunix:#{socket}")
+ output = listener.process(env, input)
+ message "listener #{number} has finished, writing output"
+end
+$stdout.write output
+$stdout.flush
+$stdout.close \ No newline at end of file