From 9e4f5f33974b018fe4b6eba2766af263f8b06951 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 4 Jul 2005 19:16:28 +0000 Subject: Added an EXPERIMENTAL gateway.cgi for getting high-speed performance through vanilla CGI using a long-running, DRb-backed server in the background (using script/listener and script/tracker) #1603 [Nicholas Seckar] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1676 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- railties/bin/tracker | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 railties/bin/tracker (limited to 'railties/bin/tracker') diff --git a/railties/bin/tracker b/railties/bin/tracker new file mode 100644 index 0000000000..3a0c3aafc9 --- /dev/null +++ b/railties/bin/tracker @@ -0,0 +1,106 @@ +require "drb" + +VERBOSE = false + +class Tracker + include DRbUndumped + + def initialize(timeout = 90, uri = nil) + @timeout = timeout + @waiting = [] + @working = [] + + @waiting_mutex = Mutex.new + + DRb.start_service(uri, self) + @uri = DRb.uri + end + def run + start_listener 3 + sleep 3 + + background + end + + def register_listener(listener) + @waiting.push listener + nil + end + def remove_listener(listener) + @waiting.delete listener + @working.delete listener + nil + end + + def with_listener + listener = @waiting.shift + unless listener + start_listener(2) unless @waiting.length + @working.length > 6 + @waiting_mutex.synchronize do + 10.times do + sleep 0.5 + listener = @waiting.shift + break if listener + end + unless listener + ($stderr.puts "Dropping request due to lack of listeners!!!" unless listener) if VERBOSE + return + end + end + end + + @working << listener + yield listener + ensure + if listener + @working.delete listener + @waiting << listener + end + end + + def background + loop do + @timeout ? sleep(@timeout) : sleep + unless @processed + $stderr.puts "Idle for #{@timeout} -- shutting down tracker." if VERBOSE + Kernel.exit 0 + end + @processed = false + end + end + + def process(input) + output = nil + $stderr.puts "tracker: received request.. obtaining listener" if VERBOSE + with_listener do |listener| + $stderr.puts "tracker: obtained -- forwarding request to listener.." if VERBOSE + @processed = true + output = listener.process(input) + $stderr.puts "tracker: listener released control." if VERBOSE + end + return output + end + + def start_listener(n = 1) + tracker_uri = @uri + listener_path = File.join(File.dirname(__FILE__), 'listener') + fork do + exec 'ruby', listener_path, 'start-listeners', tracker_uri, n.to_s + end + end + + def ping + true + end +end + +if ARGV.first == "start" + tracker = Tracker.new(90, ARGV[1]) + socket = (/druby:([^?]*)\?/ =~ ARGV[1]) ? $1 : nil + require 'fileutils' if socket + + begin tracker.run + ensure + FileUtils.rm_f(socket) if socket + end +end -- cgit v1.2.3