Ruby Timeout没有超时

时间:2017-07-31 08:12:01

标签: ruby-on-rails ruby firebird

我使用firebird数据库gem连接到用户指定的数据库。只要用户提供正确的数据,它就可以正常工作。如果没有,gem无法连接,并且gem抛出异常需要很长时间。我尝试过使用超时:超时如下:

database = Fb:Database(connection_data)
Timeout::timeout(5) do
  database.connect #that's the part that takes long to connect
end

但它没有超时。它只是等待(这是一个漫长的等待,超过一分钟),并抛出宝石异常(它不是超时异常)。似乎代码执行时间低于5秒(根据Timeout),除了花了1-2分钟。我一直在寻找解释(检查源代码),但没有找到任何解释。我真的不想修复它(因为它会被转移到延迟的工作),但我想知道为什么,你怎么能忽略Timeout。

此外,下面的代码工作正常。

Timeout::timeout(5) do
  sleep(10)
end

1 个答案:

答案 0 :(得分:1)

超时块在新线程中运行代码,当timeout在5秒后发生时,异常被强制引发(Thread.raise我相信)进入运行database.connect的线程。 (Timeout module code

这种中断可能发生在任何一条线上;在这种情况下,它可能在某种救援块中(并在之后抛出自定义错误)或任何无法正确处理它的地方,使其处于无效状态。图书馆不太可能在任何地方进行防御性编码

您可以详细了解在this Reddit thread中使用Timeout::timeout的问题。