西@九大です。

From: matz / netlab.co.jp (Yukihiro Matsumoto)
> 西さん辺りに実際のコードを出して頂けると参考になると思うので

呼ばれてノコノコ出て来た訳じゃないんですが、(イヤ、ほんまはその通りな
んですけど)実例として、稚拙ながら、私が利用している TimeStampObserver
というものを添付させて頂きます。

これは、指定された「Web の URL」や「ファイルのパス」からタイムスタンプ
(Web の場合は Last-Modified)を取得するだけのものなんですが、以下のよう
に「よく見る Web 関係の更新チェック」に利用できます。
#下記のサイトが「Last-Modified」を返すかどうかは知りませんが。

----------------------------------------------------------------------
#!/usr/local/bin/ruby

require "TimeStampObserver"

URIS = ["http://www.netlab.co.jp/ruby/jp/", "http://iij.asahi.com/", "file:."]
  
array = []

URIS .each do |uri|
  if observer = TimeStampObserver .new(uri)
    observer .seek # same as `.start'
    array << observer
  end
end

sleep 3

array .each do |observer|
  if observer .status
    observer .stop
    #      タイムアウト処理はここ
    p 'timeout!'
  else
    #      通常処理はここ
  end
end

array .sort .reverse .each do |observer|
  p [observer .uri, observer .time]
end
----------------------------------------------------------------------

タイムアウトとは直接関係ありませんが、一応、Thread と socket を利用し
ているという事で、参考になれば幸いです。

------------------------------------------------------------------
九州大学大学院システム情報科学研究科 情報工学専攻 博士後期課程二年
      西 和則   ( e-mail: kazunori / swlab.csce.kyushu-u.ac.jp )
------------------------------------------------------------------

require "socket" require "thread" ###################################################################### ### Class TimeStampObserver ### aTimeStampObserver accepts an URI for a constructor argument ### and gets the time stamp of it by `seek'(or `start') method. ### ### Author: Kazunori NISHI <kazunori / swlab.csce.kyushu-u.ac.jp> ### Created: Jun 10, 1998 ### Revised: Oct 9, 1998 ### class TimeStampObserver MONTH = { 'jan', 1, 'feb', 2, 'mar', 3, 'apr', 4, 'may', 5, 'jun', 6, 'jul', 7, 'aug', 8, 'sep', 9, 'oct', 10, 'nov', 11, 'dec', 12} attr :uri attr :time attr :method attr :locate attr :thread # 初期化。 def initialize (uri) @time # 最終改竄時刻(unix 秒) @uri # 時刻を取る URI @method # 時刻を取る手段 @locate # 時刻を取る対象の場所(ファイル名など) @thread # 自分が使うスレッド @method, @locate = (@uri = uri) .split(/:/, 2) end # 定義された手段(@method)によって、時刻を取得し、@time に入れる def get_last_modified @time = case @method .downcase when "file"; self .get_time_stamp_local(@locate) when "http"; self .get_time_stamp_remote(@uri) when "const"; @uri .to_i when "comment"; 0 end .to_i return self end def seek @thread = Thread .new {self .get_last_modified} end def stop if seeking? @time = 0 @thread .exit end end def seeking? (@thread && @thread .status) end def <=> (other) @time <=> other .time end ###################################################################### ## get time stamp of a local file ###################################################################### def get_time_stamp_local (file) File::mtime(file) .to_i end ###################################################################### ## Get last modified of a remote file by http ###################################################################### def get_last_modified_by_http (url) begin if url =~ /http:\/\/([^\/]*)/ host, port = $1 .split(/:/, 2) s = TCPsocket.open(host, port || 80) s .write("HEAD " + url + " HTTP/1.0\n\n") while s .gets() return $_ if /^(Last-Altered:|Last[- ]Modified:)/i end end return nil rescue return nil end end def get_time_stamp_remote (uri) case self .get_last_modified_by_http (uri) # Last-Modified: Sun, 08 Mar 1998 13:49:00 GMT when /^Last-Altered: (.*)$/i return $1 .to_i when /^Last[- ]Modified: (.*)$/i week, day, mon, year, hour, min, sec = $1 .split(/[: ]/) return Time.gm(year.to_i - 1900, MONTH[mon.downcase], day.to_i, hour.to_i, min.to_i, sec.to_i) .to_i else return -1 end end alias start seek alias status seeking? end