如何在 Ruby 2 中为 Net::HTTP::Post.new 请求指定读取超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19547184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to specify a read timeout for a Net::HTTP::Post.new request in Ruby 2
提问by Jane
I have a post happening to a rails application from a ruby script. The script creates a variable request as
我有一篇关于 ruby 脚本的 Rails 应用程序的帖子。该脚本创建一个变量请求作为
request = Net::HTTP::Post.new(url.path)
which is then used as follows
然后按如下方式使用
request.content_type = "application/json"
request.body = JSON.generate( params )
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
There is quite a lot of processing happening on the server side, and I'm getting a Net::ReadTimeouterror
服务器端有相当多的处理发生,我收到一个Net::ReadTimeout错误
I tried to specify a timeout period
我试图指定一个超时期限
request.read_timeout = 500
as per this stackoverflow answerbut I got a
根据这个stackoverflow答案,但我得到了
undefined method `read_timeout=' for #<Net::HTTP::Post POST> (NoMethodError)
error. I assume that I'm missing something simple somewhere. All clues gratefully received
错误。我认为我在某处遗漏了一些简单的东西。感激地收到所有线索
Technical info:
技术信息:
- Ruby 2.0.0p247
- Rails 4.0.0
- Windows 7 32 bit ruby
- 红宝石 2.0.0p247
- 导轨 4.0.0
- Windows 7 32 位红宝石
回答by Jane
Solved via this stackoverflow answer
I've changed my
我改变了我的
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
line to be
线要
response = Net::HTTP.start(url.host, url.port, :read_timeout => 500) {|http| http.request(request)}
and this seems to have got around this problem.
这似乎解决了这个问题。
回答by Patrick Oscity
The read_timeoutis available with a plain Net::HTTPobject:
在read_timeout与一个普通的可用Net::HTTP对象:
url = URI.parse('http://google.com')
http = Net::HTTP.new(url.host, url.port)
http.read_timeout = 5 # seconds
http.request_post(url.path, JSON.generate(params)) do |response|
# do something with response
p response
end
回答by Lemon Cat
One thing to keep in mind is that if read_timeoutis set to a small value such that a timeout doesoccur...Net::HTTPwill "helpfully" retry the request. For a slow HTTP server, a timeout error may not be raised to the code calling Net::HTTPuntil 2xthe read_timeoutvalue.
有一点要记住的是,如果read_timeout设置为一个很小的值,使得超时不发生......Net::HTTP将“很有帮助”重试请求。对于一个缓慢的HTTP服务器,超时错误可能不会提高到代码中调用Net::HTTP,直到2倍的read_timeout值。
This certainly was not the behavior I expected.
这当然不是我期望的行为。
More info on this topic and how possible solutions differ for Ruby < 2.5 and >= 2.5 may be found here:
可以在此处找到有关此主题的更多信息以及 Ruby < 2.5 和 >= 2.5 的可能解决方案有何不同:
回答by Webb Lu
I catch both OpenTimeout and ReadTimeout and it's work. test in Ruby:2.6.5
我抓住了 OpenTimeout 和 ReadTimeout 并且它的工作。在 Ruby 中测试:2.6.5
def ping(host, port)
begin
url = URI.parse("http://#{host}:#{port}/ping")
req = Net::HTTP::Get.new(url.to_s)
# setting both OpenTimeout and ReadTimeout
res = Net::HTTP.start(url.host, url.port, :open_timeout => 3, :read_timeout => 3) {|http|
http.request(req)
}
if JSON.parse(res.body)["ok"]
# return true
STDERR.puts "#{host}:#{port} is reachable"
else
STDERR.puts "#{host}:#{port} is NOT reachable"
end
rescue Net::ReadTimeout => exception
STDERR.puts "#{host}:#{port} is NOT reachable (ReadTimeout)"
rescue Net::OpenTimeout => exception
STDERR.puts "#{host}:#{port} is NOT reachable (OpenTimeout)"
end
end
ping("#{ENV['FIRST_HOST']}", 2345)
ping("#{ENV['SECOND_HOST']}", 2345)
回答by Shadman
If anyone is still facing timeout setting issue and Net::HTTPtimeout not working as expected, then you may follow below approach as well:
如果有人仍然面临超时设置问题并且Net::HTTP超时未按预期工作,那么您也可以遵循以下方法:
begin
Timeout::timeout(10) {
####
## YOUR REQUEST CODE WILL BE HERE
####
}
rescue
408
end

