aboutsummaryrefslogtreecommitdiffstats
path: root/railties/bin/tracker
diff options
context:
space:
mode:
Diffstat (limited to 'railties/bin/tracker')
-rw-r--r--railties/bin/tracker149
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