diff options
Diffstat (limited to 'railties/bin/tracker')
-rw-r--r-- | railties/bin/tracker | 149 |
1 files changed, 54 insertions, 95 deletions
diff --git a/railties/bin/tracker b/railties/bin/tracker index 17fce67e54..859c9fa0e0 100644 --- a/railties/bin/tracker +++ b/railties/bin/tracker @@ -1,110 +1,69 @@ -require "drb" -require "rbconfig" +#!/usr/local/bin/ruby -VERBOSE = false +require 'drb' +require 'thread' + +def message(s) + $stderr.puts "tracker: #{s}" if ENV && ENV["DEBUG_GATEWAY"] +end 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 + + def initialize(instances, socket_path) + @instances = instances + @socket = File.expand_path(socket_path) + @active = false + + @listeners = [] + @instances.times { @listeners << Mutex.new } + + message "using #{@listeners.length} listeners" + message "opening socket at #{@socket}" + + @service = DRb.start_service("drbunix://#{@socket}", self) 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 + message "listener requested" + + mutex = has_lock = index = nil + 3.times do + @listeners.each_with_index do |mutex, index| + has_lock = mutex.try_lock + break if has_lock end + break if has_lock + sleep 0.05 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 + + if has_lock + message "obtained listener #{index}" + @active = true + begin yield index + ensure + mutex.unlock + message "released listener #{index}" end - @processed = false + else + message "dropping request because no listeners are available!" 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( - File.join(Config::CONFIG['bin_dir'], Config::CONFIG['RUBY_SO_NAME']), - listener_path, 'start-listeners', tracker_uri, n.to_s - ) + + def background(check_interval = nil) + if check_interval + loop do + sleep check_interval + message "Idle for #{check_interval}, shutting down" unless @active + @active = false + Kernel.exit 0 + end + else DRb.thread.join 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 +socket_path = ARGV.shift +instances = ARGV.shift.to_i +t = Tracker.new(instances, socket_path) +t.background(ARGV.first ? ARGV.shift.to_i : 90)
\ No newline at end of file |