Ruby超时不​​超时 [英] Ruby Timeout not timing out

查看:128
本文介绍了Ruby超时不​​超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebird数据库 gem 连接到用户指定的数据库.只要用户提供正确的数据,它就可以正常工作.如果没有,gem无法连接,gem将引发异常需要很长时间.我试图像这样使用Timeout:timeout:

I'm using a firebird database gem to connect to a user specified database. It works fine as long as user provides correct data. If not, gem cannot connect, and it takes a very long time before gem throws an exception. I've tried to use Timeout:timeout like this:

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

但是它并不超时.它只是等待(这是一个漫长的等待,超过一分钟),然后抛出gem异常(这不是Timeout异常).似乎代码在5秒钟内执行了(根据超时),只是花了1-2分钟.我一直在寻找解释(也正在检查源代码),但没有找到任何解释.我真的不是想要解决此问题(因为无论如何它都会被转移到延迟的工作中),但是我想知道原因,以及如何忽略超时.

But it does not time out. It simply waits (and it is a long wait, more than a minute), and throws gem exception (it's not Timeout exception). It seems like the code executed below 5 seconds (according to Timeout), except it took it 1-2 minutes. I've been looking for an explanation (checking the source code as well), and didn't find any. I don't really want a fix to it (because it will be moved to delayed job anyway), but I would like to know why, and how can you ignore Timeout.

此外,下面的代码也可以正常工作.

Also, the code below works fine.

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

推荐答案

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

The timeout block runs the code in a new thread and when the timeout happens after 5 seconds, the exception is forcefully raised (Thread.raise I believe) into the thread running database.connect. (Timeout module code)

该中断可能发生在任何行上;在这种情况下,它可能处于某种形式的救援块中(并在之后引发自定义错误),或者在任何无法正确处理它的地方都处于无效状态.对于一个库,无处不在进行防御性编码是非常不可能的.

That interruption could happen on any line; it could be in some sort of rescue block in this case (and throwing a custom error after) or anywhere that does not handle it properly leaving it in an invalid state. It is highly unlikely for a library to be able to be coded defensively everywhere.

您可以在Timeout::timeout的问题的信息. >此Reddit线程.

You can read more about the problems of using Timeout::timeout in this Reddit thread.

这篇关于Ruby超时不​​超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆