如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:54:54  来源:igfitidea点击:

How to specify a read timeout for a Net::HTTP::Post.new request in Ruby 2

ruby-on-railsruby

提问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

通过此stackoverflow 答案解决

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 的可能解决方案有何不同:

https://stackoverflow.com/a/59186209/5299483

https://stackoverflow.com/a/59186209/5299483

回答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