【问题标题】:Ruby 2.3 - Adding Timeout error and notification to net:http requestRuby 2.3 - 向 net:http 请求添加超时错误和通知
【发布时间】:2018-07-12 18:24:13
【问题描述】:

我有一个工作系统可以产生错误并将它们发送给活动管理员使用。

例如在 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”,应用程序会崩溃并显示"H12 error"

我想在上面的代码中添加两件事 - 超时:我认为我需要 read_timeout 和 open_timeout 并且 read_timeout + open_timeout 应该是

  • 如果请求在 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 秒,我无法创建代码来捕获和删除此请求...

【问题讨论】:

  • 您是否尝试使用 Timeout.timeout { }` 块包裹您的 get_url_http_response(url)
  • 没有不知道这个方法!看起来确实与我的需要非常相关。将检查它,看看如何使用它。我还需要捕获 fatc 超时使请求“丢弃”以使用我当前的系统发送通知(请参阅问题)

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


【解决方案1】:

这不是很漂亮的解决方案(请参阅: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

【讨论】:

  • hehe 2 分钟前也偶然发现了这篇文章 :) 他们在 cmets 中说,即使我选择 get_response read_timeout 或 write_timeout 参数,ti 仍会在后台使用 Timeout “请注意,Net: :HTTP 仍在为 open_timeout 使用超时,如 github.com/ruby/rub... ... 至少 read_timeout 现在实现得更好"
  • 成功了!谢谢,将在 22 小时内分配积分,因为它在此之前被 SO 阻止
猜你喜欢
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多