From: Kazunori NISHI Date: 1998-10-09T12:39:57+09:00 Subject: [ruby-list:9921] Re: signal 関係 西@九大です。 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 ### 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