#!/usr/bin/env ruby require 'drb' require 'thread' def message(s) $stderr.puts "tracker: #{s}" if ENV && ENV["DEBUG_GATEWAY"] end class Tracker include DRbUndumped 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 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 if has_lock message "obtained listener #{index}" @active = true begin yield index ensure mutex.unlock message "released listener #{index}" end else message "dropping request because no listeners are available!" end end 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 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)