read_body の抜け方。

さっきの続きで次のようなコードを考えてみた。

$lasttime = Time.now
def proc(uri)
  begin
    t = Thread.new {
            while true
                    if(Time.now - $lasttime > TIMEOUT_SECONDS)
                            raise "Read Chunk Timeout"
                    end
                    sleep TIMEOUT_SECONDS
            end
    }
    Net::HTTP.start(uri.host, uri.port) { |http|
            req = Net::HTTP::Post.new(uri.request_uri)
            req.set_form_data({'track' => TRACK, 'follow' => FOLLOW }, '&')
            req.basic_auth(TWITTER_SCREEN_NAME, TWITTER_PASSWORD)
            http.request(req) { |response|
                    response.read_body { |chunk|
                            subproc(chunk)
                            $lasttime = Time.now
                    }
            }
    }
  rescue
    t.kill
    return
  end
end

read_body のブロックの中では、chunk が読まれるたびに $lasttime の値が最新の時刻に更新される。 これとは別に動いているスレッドでは $lasttime と現在時刻との差を常に監視している。 $lasttime が現在時刻と比べて TIMEOUT_SECONDS よりも小さくなっているということは、 read_body がうまくループしてないことを意味する。 そこでこのスレッドは例外を発生させて、 rescue で例外処理に移ることによって read_body ブロックを強制的に抜けて、スレッド自身も kill して後片付けする。 どうよ。

$lasttime をグローバル変数にする必要はないのかもしれん。proc() の中の変数にしても良いのではないかと思うのだが、 スレッド間で共有しているので、念のため。