2014-09-26 4 views
1

Я хочу посмотреть время, необходимое для доступа к URL-адресу, используя Benchmark в коде ниже. Я также пытался сделать то же самое без тестов. То есть, получить время в начале теста и окончания теста, вычесть их, чтобы получить время. Оба метода заканчиваются одной и той же ошибкой тайм-аута.Предотвращение таймаута при подключении к URL-адресу

require 'open-uri' 
require 'benchmark' 

response = nil 
puts "opening website with benchmark..." 
puts Benchmark.measure{ 
    response = open('http://mywebsite.com') 
} 

puts "Done !" 
status = response.status 
puts status 

Ошибка:

opening website with benchmark... 
C:/ruby/lib/ruby/1.8/timeout.rb:64:in `rbuf_fill': execution expired (Timeout::Error) 
    from C:/ruby/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill' 
    from C:/ruby/lib/ruby/1.8/net/protocol.rb:116:in `readuntil' 
    from C:/ruby/lib/ruby/1.8/net/protocol.rb:126:in `readline' 
    from C:/ruby/lib/ruby/1.8/net/http.rb:2028:in `read_status_line' 
    from C:/ruby/lib/ruby/1.8/net/http.rb:2017:in `read_new' 
    from C:/ruby/lib/ruby/1.8/net/http.rb:1051:in `request' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:248:in `open_http' 
    from C:/ruby/lib/ruby/1.8/net/http.rb:543:in `start' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:242:in `open_http' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:616:in `buffer_open' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:164:in `open_loop' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:162:in `catch' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:162:in `open_loop' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:132:in `open_uri' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:518:in `open' 
    from C:/ruby/lib/ruby/1.8/open-uri.rb:30:in `open' 
    from C:/code/test.rb:7 
    from C:/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure' 
    from C:/code/test.rb:6 

Когда я пытаюсь подключиться к этому URL в браузере, это занимает около 2-3 минут для доступа, все время.

Я искал Google, но не нашел полезных ответов на мою проблему. Я знаю, что у меня есть , чтобы изменить тайм-аут для чего-то, но не в состоянии выяснить, какой из них. Кто-то может помочь?

ответ

9

Используйте :read_timeout параметр, указанный в секундах, например,

open('foo.com', :read_timeout => 10) 

http://ruby-doc.org/stdlib-1.8.7/libdoc/open-uri/rdoc/OpenURI/OpenRead.html

+0

Спасибо. Как установить тайм-аут на бесконечность? Не удалось получить этот ответ быстро из ссылки, которую вы дали. time out = -1 ??? –

+0

Я получаю сообщение об ошибке - 'синтаксическая ошибка, неожиданная ':', expecting ')' response = open (url, read_timeout: 300)' –

+0

@BoratSagdiyev ... Вероятно, вы должны использовать правильный синтаксис карты для своей версии Ruby тогда. Я отредактирую свой ответ, но возможность экстраполяции из образцов кода - это ценное умение. –

0

Вы всегда можете обернуть это в Timeout:

Timeout.timeout(5) do 
    response = open('http://mywebsite.com') 
end 

Это будет бросать исключение Timeout::Error вам нужно поймать.

+0

Есть ли недостатки в использовании этого метода? Благодарю. –

+0

'open' уже поднимает' Timeout' на 60 секунд. – Matt

+0

При использовании библиотеки Timeout могут быть последствия - http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/. – plainjimbo

2

BufferedIO класс, который использует Net::HTTP для соединения, которое open-uri затем использует для запроса имеет read_timeout attribute set to 60 seconds.

Класс Net::HTTP обеспечивает setter read_timeout for that.

К сожалению, способsets up этот запрос не предоставляет вам способ получить эту настройку перед запросом или легко переопределить значение по умолчанию 60.

Возможно, вам понадобится использовать Net::HTTP.

link = URI.parse(url) 
request = Net::HTTP::Get.new(link.path) 
response = Net::HTTP.start(link.host, link.port) {|http| 
    http.read_timeout = 100 #Default is 60 seconds 
    http.request(request) 
} 

Код украдена из this answer

редактирования: или обновить до 1.9, который поддерживает :read_timeout = x вариант Дэйв Ньютон отметил.

+0

Спасибо. Это хороший ответ. –

Смежные вопросы