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

后端 未结 5 1079
生来不讨喜
生来不讨喜 2021-01-01 13:26

I have a post happening to a rails application from a ruby script. The script creates a variable request as

request = Net::HTTP::Post.new(url.path)


        
相关标签:
5条回答
  • 2021-01-01 14:01

    I catch both OpenTimeout and ReadTimeout and it's work. test in 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)
    
    0 讨论(0)
  • 2021-01-01 14:03

    If anyone is still facing timeout setting issue and Net::HTTP timeout not working as expected, then you may follow below approach as well:

    begin
        Timeout::timeout(10) {
            ####
            ## YOUR REQUEST CODE WILL BE HERE
            ####
        }
    rescue
        408
    end
    
    0 讨论(0)
  • 2021-01-01 14:04

    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.

    0 讨论(0)
  • 2021-01-01 14:04

    One thing to keep in mind is that if read_timeout is set to a small value such that a timeout does occur...Net::HTTP will "helpfully" retry the request. For a slow HTTP server, a timeout error may not be raised to the code calling Net::HTTP until 2x the read_timeout value.

    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:

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

    0 讨论(0)
  • 2021-01-01 14:12

    The read_timeout is available with a plain Net::HTTP object:

    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
    
    0 讨论(0)
提交回复
热议问题