gethostbyname で timeout できない
timeout は Thread で実現されているため、C レベルで停止してしまう (Threadの切替えが発生しない)処理に対しては効果がありません。
以下の例では、gethostbyname(およそ0.6秒処理に時間がかかっている) が終了し た直後((A)の箇所)で TimeoutError 例外があがっています。
require 'timeout' require 'socket' start = Time.now begin timeout(0.1) { p TCPSocket.gethostbyname("www.ruby-lang.org") # (A) } ensure p Time.now - start end => ["helium.ruby-lang.org", [], 2, "210.251.121.214"] 0.689331 /usr/local/lib/ruby/1.6/timeout.rb:37: execution expired (TimeoutError) from -:6:in `timeout' from -:6
Rubyでかかれたリゾルバを利用するという回避策があります。
require "resolve-replace"
すると、resolve.rb
で定義された、
リゾルバが利用されるようになります。
cygwin や mingw では以下もダメという報告があります。同じ理由かも知れ ません(本来、入力待ちの状態では入力を監視しつつThread切替えを行うので 大丈夫なはずなのですが)
require 'timeout' begin timeout(5) do $stdin.gets end rescue TimeoutError print "timeout\n" end