Ruby Timeout not timing out

拈花ヽ惹草 提交于 2019-12-24 20:12:05

问题


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

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

回答1:


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.

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



来源:https://stackoverflow.com/questions/45410527/ruby-timeout-not-timing-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!