#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
После использования тайм-аута:
status = Timeout::timeout(5) {
# Something that should be interrupted if it takes too much time...
}
Я получил эту ошибку тайм-аута:
/Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/net/http.rb:644:in `initialize': execution expired (Timeout::Error)
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/net/http.rb:644:in `open'
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/net/http.rb:644:in `block in connect'
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/timeout.rb:44:in `timeout'
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/timeout.rb:87:in `timeout'
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/net/http.rb:644:in `connect'
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/net/http.rb:637:in `do_start'
from /Users/galharth/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/net/http.rb:632:in `start'
from /Users/galharth/.rvm/gems/ruby-1.9.2-p136/gems/mechanize-1.0.0/lib/mechanize.rb:527:in `fetch_page'
from /Users/galharth/.rvm/gems/ruby-1.9.2-p136/gems/mechanize-1.0.0/lib/mechanize.rb:259:in `get'
Что мне делать?
Комментарии:
1.
status = Timeout::timeout(5) { puts "ok" }
Сбой?2. Я только что протестировал на ruby1-9-2- p180 — проблемы нет
3. Моя интуиция подсказывает мне, что вы должны приложить усилия, чтобы предотвратить возникновение тайм-аута, если это возможно. Можете ли вы разделить этот единственный запрос на несколько меньших запросов?
4. @yock, вы не можете контролировать поведение Интернета. Один запрос для небольшой страницы может занимать минуты. Это не имеет ничего общего с количеством запросов, это скорость реагирования хоста, возвращающего запрос.
5. Все зависит от причины длительного времени отклика. Если вызов API выполняется медленно из-за того, что он возвращает много данных, вы, вероятно, могли бы разбить этот вызов на множество меньших вызовов. Итак, нет, вы не всегда действуете по указке Интернета.
Ответ №1:
Что ж, это ожидаемое поведение Timeout
. Если блок занимает слишком много времени, его выполнение завершается и генерируется исключение.
Вероятно, вы хотели бы перехватить исключение и обработать его соответствующим образом:
require 'timeout'
begin
status = Timeout::timeout(5) {
# Something that should be interrupted if it takes too much time...
}
rescue Timeout::Error
puts 'That took too long, exiting...'
end
Комментарии:
1.
Timeout
распространенным исключением являетсяTimeout::Error
. Вот еще одна проблема2. Будет ли блок восстановления обрабатывать Timeout::Error?
3. @yock «Будет ли блок восстановления обрабатывать Timeout::Error?» Из документации по тайм-ауту :
If the block execution terminates before sec seconds has passed, it returns the result value of the block. If not, it terminates the execution and raises exception (which defaults to Timeout::Error).
4. Я понимаю, что он выдает «исключение», но его тип — «Прерывание», не так ли? AFAIK, блок восстановления улавливает только StandardError и его подтипы.
5.Вы действительно можете
rescue
это.Timeout::Error.ancestors
выдаетTimeout::Error
RuntimeError
StandardError
Exception
Object
Kernel
BasicObject
Ответ №2:
uri = URI.parse("https://example.com")
# Full control
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
#http.read_timeout = 500
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data({"locationcode" => "999", "sublocationcode" => "1"})
response = http.request(request)
render :json => response.body