ruby / ruby/timeout

Timeout::ExitException can be raised by nested timeouts

オープン
#52 コメント 6 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Ruby
スター
168
フォーク
33
平均マージ
5時間 58分
マージ済み PR(30日)
3

説明

Behavior

Nested timeout blocks can result in a Timeout::ExitException being raised, rather than a Timeout::Error

How to reproduce

The below will sometimes raise a Timeout::ExitException, sometimes a Timeout::Error (roughly 50/50).
  

begin
  Timeout.timeout(2) do
    Timeout.timeout(2) do
      sleep 3
    end
  end
rescue Exception => e
  puts "raised a #{e.class}"
end
Cause (maybe)

Hacking up the Timeout module as follows:

module Timeout
  class Error
    def self.handle_timeout(message) # :nodoc:
      exc = ExitException.new(message)

      begin
        puts "yield #{exc.object_id} (#{message})"
        yield exc
      rescue ExitException => e
        puts "test #{e.object_id} vs #{exc.object_id} => #{exc.equal?(e)} (#{message})"
        raise new(message) if exc.equal?(e)
        puts "re-raise #{e.object_id}('#{e}') (#{message})"
        raise
      end
    end
  end
end

Timeout.timeout(2, nil, "outer timeout") do
  Timeout.timeout(2, nil, "inner timeout") do
    sleep 3
  end
end

shows that, when an ExitException is raised, the "inner" exception is being caught by the "outer" handle_timeout block. Suspicious this is the result of indeterminate Thread#raise behavior?

Environment

Ruby 3.3.5
Timeout 0.4.1
Ubuntu 24.04.1 running on WSL2

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、issue にあるネストした Timeout.timeout の再現コードを実行し、Timeout.timeout の経路、特に Timeout::Error.handle_timeout と ExitException の処理を調査します。内部の例外が外側のハンドラーに到達できる条件を確認します。完了条件は、再現コードに対するリグレッションチェックを追加し、ネストしたタイムアウトが一貫して Timeout::ExitException ではなく Timeout::Error を発生させることです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
ruby
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
42/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。