Ruby 2.3 - 向net:http请求

时间:2018-02-02 09:24:48

标签: ruby-on-rails ruby ruby-on-rails-4 heroku net-http

我有一个工作系统来产生错误并将它们发送给Active Admin使用。

例如,在Active admin中,对于CMS的特定页面,页面可能会执行:

url_must_be_accessible("http://www.exmaple.com", field_url_partner, "URL for the partner")

这会使用以下代码向Active Admin Editor发送不同类型的错误通知:

module UrlHttpResponseHelper

  def url_must_be_accessible(url, target_field, field_name)      
    if url
      url_response_code = get_url_http_response(url).code.to_i
      case url_response_code
      when -1                                                         
        # DNS issue; website does not exist; 
        errors.add(target_field,
          "#{field_name}: DNS Problem -> #{url} website does not exist")
      when 200
        return 
      when 304
         return
      else
        errors.add(target_field,
          "#{field_name}: #{url} sends #{url_response_code} response code")
      end
    end
  end

  def get_url_http_response(url)  
    uri = URI.parse(URI.encode(url))
    request = Net::HTTP.get_response(uri)
    return request
  rescue Errno::ECONNREFUSED, SocketError => e
    OpenStruct.new(code: -1)
  end

end

在本地模式下,这非常有用!但是在制作中,我们使用Heroku,当一个请求pn Heroku超过30秒时就好像你试试这个链接" http://www.exmaple.com",应用程序崩溃了{{3 }}

我想在上面添加两个代码 - 超时:我认为我需要read_timeout和open_timeout,并且read_timeout + open_timeout应该是< 30秒,让我们采取一些安全措施,更好的< 25秒

  • 如果请求仍然是"正在" 25秒后,通过放弃/放弃请求避免达到30秒

  • 并抓住这个"我们故意放弃了请求,因为超时的风险"通过向用户发送通知。我希望使用我当前的系统,其中包括:

     rescue Errno::ECONNREFUSED, SocketError => e
        OpenStruct.new(code: -7) # = some random number
      end
    
    case url_response_code
    when -7
      errors.add(target_field,
              "#{field_name}: We tried to reach #{url} but this takes too long and risks crashing the app. please check the url and try again.")
    

我如何创建一个像-1这样的代码,但另一个代码来拯救这个"超时" /"删除请求尝试"我自己强制执行。

尝试但没有任何作用。如果达到25秒,我无法创建捕获代码并删除此请求...

1 个答案:

答案 0 :(得分:3)

这不是一个非常漂亮的解决方案(参见:https://medium.com/@adamhooper/in-ruby-dont-use-timeout-77d9d4e5a001),但我相信你仍然可以在这里使用它,因为你只有一个事情发生在链接中的示例的对面,其中多个动作可能导致非 - 明显的行为:

def get_url_http_response(url)
  uri = URI.parse(URI.encode(url))
  request = Timeout.timeout(25) { Net::HTTP.get_response(uri) }
  return request
rescue Errno::ECONNREFUSED, SocketError => e
  OpenStruct.new(code: -1)
rescue Timeout::Error
  # return here anything you want
end