http://www.pistolfly.jp/weblog/2011/06/open-uritimeout.html
Time out時間を1秒に設定。
1秒たって接続できなければあきらめる。
require "rubygems" require "mechanize" require "hpricot" require "kconv" require "uri" #require "timeout" require "resolv-replace" $KCODE="u" agent=Mechanize.new() #Time out agent.read_timeout=3; agent.open_timeout=3; agent.max_history=1; URL2="http://yahoo.com.jp" begin page=agent.get(URL2) puts page.header rescue Mechanize::ResponseCodeError => ex puts ex.response_code; end #begin # begin #timeout(0.1){ # page=agent.get(URL2) # puts page.header #sleep 30; #} # rescue Timeout::Error # puts "Timeout!" # end #rescue Mechanize::ResponseCodeError => ex # puts ex.response_code; #end
上記URLより
timeout による割り込みはRubyのThreadによって実現されており、C言語レベルで実装されRuby のスレッドが割り込めない処理では無効なので、SocketでDNSの名前解決に時間がかかった場合にタイムアウトしない。そのため、resolvライブラリを使うようにresolv-replaceでメソッドの書き換えを行う。
タイムアウト時のTimeoutErrorはStandardErrorのサブクラスではないので、捕捉するためには明示的に捕捉するクラス(TimeoutError)をrescueに指定する必要がある。