👏
[Bug #20314] Timeout.timeout がネストしている場合に同じタイミングでタイムアウトが発生した場合のバグ報告
[Bug #20314] Simultaneous Timeout expires may raise an exception after the block
- 同じタイミングでタイムアウトが発生すると
rescueした後に例外が発生するバグ報告 - どういうことかというと次のように同じ時刻で
Timeout.timeoutがネストしている場合に同時にタイムアウトが発生するとrescueでキャッチした後に例外が発生する
require "timeout"
class A < Exception
end
class B < Exception
end
begin
Timeout.timeout(0.1, A) do
Timeout.timeout(0.1, B) do
nil while true
end
end
rescue A, B => e
p $! #=> #<A: execution expired>
# このタイミングで例外が発生する
#=> test.rb:16:in `p': execution expired (B)
p :end # ここには到達せず実行されない
end
-
Timeout.timeoutがネストしているとこういう挙動になる可能性があるんですね - 修正案としては以下が提示されている
- 最も外側のタイムアウトで例外を発生させて、内側は例外を発生させないようにする
- 最も内側のタイムアウトで例外を発生させて、外側は例外を発生させないようにする
-
Thread#raise(A)されている場合、新しいThread#raise(B)はAを処理するまでブロッキングする
-
1.や2.は書き方によっては永続的にブロッキングし続ける可能性がある可能性があるみたいですね - チケットは2年前のものなのですが、コメントを読む限りだと今の所これと言った解決策はなさそうみたい
- 今は Timeout::ExitException can be raised by nested timeouts · Issue #52 · ruby/timeout の方で議論しているみたいですね?
Discussion