【问题标题】:Ruby Timeout behaves differently between 2.0 and 2.1Ruby Timeout 在 2.0 和 2.1 之间的行为不同
【发布时间】:2016-05-28 14:21:21
【问题描述】:

以下代码在 ruby​​ 2.0 和 2.1 之间的行为不同:

require 'timeout'

def scp
  begin
    puts "In begin"
    sleep 10
  rescue Exception => e
    puts "Exception found: #{e}"
  else
    puts "No exception found"
  ensure
    puts "In ensure"
  end
end

Timeout::timeout(1) do
  scp
end

在 ruby​​ 2.0 中,它给出:

In begin
Exception found: execution expired
In ensure

在 ruby​​ 2.1 中,它给出:

In begin
In ensure
t2.rb:7:in `sleep': execution expired (Timeout::Error)
    from t2.rb:7:in `scp'
    from t2.rb:18:in `block in <main>'
    from /usr/local/rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/timeout.rb:91:in `block in timeout'
    from /usr/local/rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/timeout.rb:35:in `block in catch'
    from /usr/local/rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/timeout.rb:35:in `catch'
    from /usr/local/rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/timeout.rb:35:in `catch'
    from /usr/local/rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/timeout.rb:106:in `timeout'
    from t2.rb:17:in `<main>'

它们为什么不同?

【问题讨论】:

  • 我正在 Linux 上测试 Ruby 2.2.3,我得到的行为与您的 Ruby 2.1 相同。我还看到 Timeout::Error.new.is_a?(Exception) 等于 true。

标签: ruby ruby-2.0 ruby-2.1


【解决方案1】:

这是记录在案的行为。我们可以比较 2.0.02.1.0 的 Ruby 超时模块的文档。 2.1.0 的文档说:

除非明确给出 klass,否则终止给定块所引发的异常无法在该块内救援。

如果您想在您的应用程序中保留旧的行为,您可以致电Timeout::timeout(1, Timeout::Error)。这将允许您在定时块内捕获异常。

【讨论】:

  • 多么奇怪。这种变化没有得到太多评论。我不确定它实际上有多大帮助。我很想知道最新的 JRuby 9k 是否有 2.1.0 的行为...
猜你喜欢
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
  • 2011-04-15
  • 2012-07-11
  • 1970-01-01
  • 2014-11-01
  • 1970-01-01
相关资源
最近更新 更多