Я проверяю часть кода для проверки с помощью ping-запросов набора веб-сайтов, которыми я владею регулярно, чтобы удостовериться, что они произошли.
Я использую направляющие, и до сих пор у меня есть это отвратительное тестовое действие, которое я использую для испытания его (см. ниже).
Проблема, хотя, состоит в том, что иногда это работает, и другие времена, это не будет... иногда, это пробегает код очень хорошо, другие времена, это, кажется, полностью игнорирует начать/спасти блок...
a. Я нуждаюсь в помощи, выясняя то, что проблемой является b. И рефакторинг этого, чтобы заставить его выглядеть респектабельным.
Ваша справка очень ценится.
редактирование 1: Вот обновленный код, извините он занял много времени, pastie.org снизился с тех пор вчера http://pastie.org/927201
Его все еще выполнение того же самого... пропускающего начать блок (потому что это только обновляет up_check_time)... однако, если один из сайтов испытывает таймаут, это на самом деле, обновляет все (check_msg, код и т.д.) правильно... сбивающий с толку, да?
require 'net/http'
require 'uri'
def ping
@sites = NewsSource.all
@sites.each do |site|
if site.uri and !site.uri.empty?
uri = URI.parse(site.uri)
response = nil
path = uri.path.blank? ? '/' : uri.path
path = uri.query.blank? ? path : "#{path}?#{uri.query}"
begin
Net::HTTP.start(uri.host, uri.port) {|http|
http.open_timeout = 30
http.read_timeout = 30
response = http.head(path)
}
if response.code.eql?('200') or response.code.eql?('301') or response.code.eql?('302')
site.up = true
else
site.up = false
end
site.up_check_msg = response.message
site.up_check_code = response.code
rescue Errno::EBADF
rescue Timeout::Error
site.up = false
site.up_check_msg = 'timeout'
site.up_check_code = '408'
end
site.up_check_time = 0.seconds.ago
site.save
end
end
end
В настоящее время у вас есть пустой блок rescue
для Errno :: EBADF
, поэтому при возникновении этого исключения вы не будет устанавливать site.up
на false
.
Также, пара других незначительных улучшений:
Вместо if site.uri и! Site.uri.empty?
вы можете использовать:
next if site.uri.nil? or site.uri.empty?
, чтобы пропустить эту итерацию ] каждый цикл
и избегайте отступа кода на дополнительный уровень.
И:
if response.code.eql?('200') or response.code.eql?('301') or response.code.eql?('302')
site.up = true
else
site.up = false
end
можно записать более кратко:
site.up = ['200', '301', '302'].include? response.code
Если вы приведете в порядок код с помощью некоторых из этих советов, это может помочь сузить проблему.
Вот фрагмент одной из моих программ, может быть, это поможет:
urls.each_with_index do |url, idx|
print "Processing URL #%04d: " % (idx+1)
uri = URI.parse(url)
response = nil
begin
Net::HTTP.start(uri.host, uri.port) do |http|
response = http.head(uri.path.size > 0 ? uri.path : "/")
end
rescue => e
puts "#{e.message} - #{url}"
next
end
# handle redirects
if response.is_a?(Net::HTTPRedirection)
new_uri = URI.parse(response['location'])
puts "URI redirects to #{new_uri}"
next
end
puts case response.code
when '200' then ...
when '404' then ...
else ...
end
end
Единственное, что я могу придумать, это то, что вы получаете другое исключение в вашем начальном блоке. Поскольку вы только явно спасаете Errno :: EBADF, Timeout :: Error, может показаться, что ваши start и rescue были пропущены. Вы могли бы проверить это, избавившись от Errno :: EBADF, Timeout :: Error и просто выполнив спасение, а затем поместив следующее в блок восстановления
logger.info(">>Exception was: "+$!)
. Затем просмотрите свои журналы, чтобы увидеть, какие исключения вы получаете .
Если вы следите за своими серверами, почему бы не использовать Nagios ? это бесплатно и также имеет некоторую поддержку Ruby, Здесь и Здесь .
РЕДАКТИРОВАТЬ:
Ruby GEM: http://hobodave.com/2010/01/10/simple-nagios-probes-in-ruby/