aboutsummaryrefslogtreecommitdiffstats
path: root/railties/bin/tracker
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-07-04 19:16:28 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-07-04 19:16:28 +0000
commit9e4f5f33974b018fe4b6eba2766af263f8b06951 (patch)
treee42300627db01be56744ff6732e64ea7356b2ed3 /railties/bin/tracker
parent00739dee173a675a9da94ec4c9c9e2866715fb41 (diff)
downloadrails-9e4f5f33974b018fe4b6eba2766af263f8b06951.tar.gz
rails-9e4f5f33974b018fe4b6eba2766af263f8b06951.tar.bz2
rails-9e4f5f33974b018fe4b6eba2766af263f8b06951.zip
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
Diffstat (limited to 'railties/bin/tracker')
-rw-r--r--railties/bin/tracker106
1 files changed, 106 insertions, 0 deletions
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