history

青木日記 RSS

<前の日 | この月 | 次の日>

2005-03-24

Ruby CVS HEAD + tDiary でデータ消滅 (1)

ょゎさんとこで発覚した現象だが、 Ruby CVS HEAD で tDiary を動かすとデータファイルが消える。

結論から言うと原因はこれ。 このコードは tdiary/default.rb 1.23 で入っているので、 tDiary 1.5.3 以降の全バージョンで発現すると思われる。

--- tdiary/defaultio.rb	2 Aug 2004 12:54:12 -0000	1.1.1.2
+++ tdiary/defaultio.rb	24 Mar 2005 02:11:52 -0000	1.2
@@ -189,8 +189,8 @@
 			while l = fh.gets( "\n.\n" )
 				begin
 					headers, body = TDiary::parse_tdiary( l )
-					style = headers['Format'] || 'tDiary'
-					diary = eval( "#{style( style )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
+					_style = headers['Format'] || 'tDiary'
+					diary = eval( "#{style( _style )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
 					diary.show( headers['Visible'] == 'true' ? true : false )
 					diaries[headers['Date']] = diary
 				rescue NameError

該当コードを発見する方法…… ruby に -d をつける

Ruby CVS HEAD + tDiary でデータ消滅 (2)

しかし、例外が起こるとファイルが消えるというのもそれはそれで変だな。 何が起こっているのだろう。

あー、わかった。

    def restore( fh, diaries )
           :
        (前半略)
           :
 
        # read and parse diary
        while l = fh.gets( "\n.\n" )
          begin
            headers, body = TDiary::parse_tdiary( l )
            style = headers['Format'] || 'tDiary'
            diary = eval( "#{style( style )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
            diary.show( headers['Visible'] == 'true' ? true : false )
            diaries[headers['Date']] = diary
          rescue NameError
          rescue
            raise
          end
        end
      ensure
        fh.flock( File::LOCK_UN )
      end
    end

style(style) の行で NoMethodError が起こるが それは NameError の下位クラスなので rescue されてなかったことになり、 ファイルには記録がないことになる。 で、消してるのはここか。

module tDiary
  class DefaultIO
    def transaction( date )
              :
              :
        if diaries.empty?
          File::delete( @dfile )
          # also delete parser cache
          @tdiary.store_parser_cache( date, nil, nil)
        end

ちなみに、ここはロックされてないように見える。 restore から store の間に別のプロセスが 記事を追加していたら、それを消してしまう可能性があるのではないか。 ……とは言え、相当なレアケースだからどうでもいいような気もするな。

(16:45)

名前
メールアドレス

<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|

Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved. LIRS