ruby のmechanizeで特定時間でアクセスをやめる方法: Timeoutの設定

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に指定する必要がある。