Ruby 2.3-向net:http请求添加超时错误和通知
我有一个可以产生错误并将其发送给Active Admin使用的系统.
I have a working system to produce errors and send them to be used by Active Admin.
例如在Active admin中,对于我们CMS的特定页面,该页面可能会执行:
For example in Active admin, for a specific page of our CMS, the page might execute :
url_must_be_accessible("http://www.exmaple.com", field_url_partner, "URL for the partner")
这将使用下面的代码向Active Admin编辑器发送不同类型的错误通知:
And this uses the code below to send to the Active Admin Editor different type of errors notifications:
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 ",则该应用程序崩溃,并显示.
In local mode, this worked great! But in production, we're on Heroku and when a request pn Heroku goes beyond 30 seconds like if you try on this link "http://www.exmaple.com", the app crashes with a "H12 error".
我想在代码上添加两件事 -超时:我想我既需要read_timeout也需要open_timeout,并且read_timeout + open_timeout应该小于<.到30秒,让我们采取一些安全措施,更好< 25秒
I'd like to add to the code above two things - timeouts: i think i need both read_timeout and open_timeout and that the read_timeout + open_timeout should be < to 30 seconds, with let's take some security , better < 25seconds
-
如果请求在25秒后仍然执行",则通过放弃/放弃请求
,并通过向用户发送通知来捕获此我们故意删除请求,因为存在超时风险".我想将当前系统与以下方式配合使用:
and catch this "we dropped the request intentionnally because risk of timeout" by sending a notification to the user. I'd like to use my current system with somehting along the lines of:
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的代码,但又如何创建一个代码以挽救我自己执行的此超时"/放弃请求尝试".
How can I create a code like -1 but another one to rescue this "timeout"/"drop the request attempt" that I myself enforce.
尝试过,但无济于事.如果到达25秒,我将无法创建用于捕获和删除此请求的代码...
Tried but nothing works. I don't manage to create the code for catch and drop this request if reaches 25 seconds...
那不是很好的解决方案(请参阅: https://medium.com/@adamhooper/in-ruby-dont-use-timeout-77d9d4e5a001 ),但我相信您仍然可以在这里使用它,因为您链接中与示例相反的内部只有一件事发生,其中多个动作可能导致不明显的行为:
That's not very beautiful solution (see: https://medium.com/@adamhooper/in-ruby-dont-use-timeout-77d9d4e5a001), but I believe you still can use it here, because you only have one thing happening inside opposite to the example in the link, where multiple actions could cause non-obvious behavior:
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