我正在使用Timeout::timeout(1)
一个需要超过 1 秒的过程,尽管它只是偶尔触发超时。当它发生时,rescue
每次都以不同的方式捕获它。这是我的代码示例:
require 'timeout'
...
begin
status = Timeout::timeout(1) {
open(file_url) do |foo|
feed = RSS::Parser.parse(foo)
some_method_call(arg1, arg2)
#other stuff
end
}
rescue Timeout::Error
Rails.logger.debug "Timeout"
return nil
rescue Exception => ex
Rails.logger.debug "EXCEPTION - #{ex.message}"
return nil
end
以下是我在相同输入下遇到的三种情况:
- 流程运行完成,耗时超过 60 秒
execution expired
进程超时并挂起,仅打印development.log
- 进程超时,被正确抢救,打印
"Timeout"
并development.log
返回nil
为什么这如此不一致?
更新
将超时时间减少到 0.0001 秒后,该过程会始终如预期地超时。似乎该open(file_url)
块的打开速度超过 1 秒,尽管该块内的所有内容都花费了超过 1 秒,但Timeout
只有在打开本身花费的时间超过 1 秒时才会触发。
然而,这并没有解释execution expired
异常。为了测试这一点,我将 移至块Timeout::timeout(0.0001)
内。open
代码如下所示:
require 'timeout'
...
begin
open(file_url) do |foo|
status = Timeout::timeout(0.0001) do
begin
feed = RSS::Parser.parse(foo)
some_method_call(arg1, arg2)
#other stuff
rescue Timeout::Error
Rails.logger.debug "Timeout 2"
rescue Exception => ex
Rails.logger.debug "EXCEPTION 2 - #{ex.message}"
end
end
end
rescue Timeout::Error
Rails.logger.debug "Timeout"
return nil
rescue Exception => ex
Rails.logger.debug "EXCEPTION - #{ex.message}"
return nil
end
现在,我一直在收到输出EXCEPTION 2 - execution expired
。为什么Timeout::Error
这里没有被触发?