diff options
Diffstat (limited to 'railties/bin/tracker')
-rw-r--r-- | railties/bin/tracker | 106 |
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 |