lib/kestrel/client/stats_helper.rb in kestrel-client-0.7.1 vs lib/kestrel/client/stats_helper.rb in kestrel-client-0.7.2

- old
+ new

@@ -1,31 +1,50 @@ module Kestrel::Client::StatsHelper + STATS_TIMEOUT = 3 + QUEUE_STAT_NAMES = %w{items bytes total_items logsize expired_items mem_items mem_bytes age discarded waiters open_transactions} - QUEUE_STAT_NAMES = %w{items bytes total_items logsize expired_items mem_items mem_bytes age discarded} - def sizeof(queue) stat_info = stat(queue) stat_info ? stat_info['items'] : 0 end def available_queues stats['queues'].keys.sort end def stats - merge_stats(servers.map { |server| stats_for_server(server) }) + alive, dead = 0, 0 + + results = servers.map do |server| + begin + result = stats_for_server(server) + alive += 1 + result + rescue Exception + dead += 1 + nil + end + end.compact + + stats = merge_stats(results) + stats['alive_servers'] = alive + stats['dead_servers'] = dead + stats end def stat(queue) stats['queues'][queue] end private def stats_for_server(server) server_name, port = server.split(/:/) - socket = TCPSocket.new(server_name, port) + socket = nil + with_timeout STATS_TIMEOUT do + socket = TCPSocket.new(server_name, port) + end socket.puts "STATS" stats = Hash.new stats['queues'] = Hash.new while line = socket.readline @@ -43,10 +62,12 @@ RAILS_DEFAULT_LOGGER.debug("KestrelClient#stats_for_server: Ignoring #{line}") end end stats + ensure + socket.close if socket && !socket.closed? end def merge_stats(all_stats) result = Hash.new @@ -73,8 +94,29 @@ value.to_f when /^\d+$/ value.to_i else value + end + end + + begin + require "system_timer" + + def with_timeout(seconds, &block) + SystemTimer.timeout_after(seconds, &block) + end + + rescue LoadError + if ! defined?(RUBY_ENGINE) + # MRI 1.8, all other interpreters define RUBY_ENGINE, JRuby and + # Rubinius should have no issues with timeout. + warn "WARNING: using the built-in Timeout class which is known to have issues when used for opening connections. Install the SystemTimer gem if you want to make sure the Kestrel client will not hang." + end + + require "timeout" + + def with_timeout(seconds, &block) + Timeout.timeout(seconds, &block) end end end