2009-09-03 21 views
2

私はRailsのコントローラ一時ファイルとガベージコレクション

open(source) { |s| content = s.read } 
    rss = RSS::Parser.parse(content, false) 

でこのコマンドを持っており、それが(希少)ディスクスペースを埋めている一時ファイルが得られています。

は私はある程度の問題を検討してきたし、それはこの問題が発生したスタック内のどこかで判明:

io = Tempfile.new('open-uri') 

が、それは決して明示的に閉じられていない取得し、この一時ファイルのインスタンスのように見えます。ガベージコレクション時に自動的に発生する可能性のある方法は

def _close # :nodoc: 

ですか?

何が起きているのか、どのように一時ファイルを整理するのが助けになるのですか。

答えて

1

_closeは、ファイルを閉じてから、ガベージコレクションがファイルのリンクを解除(削除)するのを待ちます。理論的には、closeの代わりにTempfileclose!メソッドを呼び出すか、close(true)(内部ではclose!)を呼び出すことで、リンクを強制的に解除することができます。

編集:しかし、問題はあなたの手の外にある、オープン-URIである - そしてそれは、それ自体の後にクリーンアップのための約束を行うものではありません:それはちょうど、ガベージコレクタが期限内にすべてのTempfile Sを確定することを前提としてい。

このような場合、ObjectSpace.garbage_collectsee here)を使用して自分自身をガベージコレクタに呼び出すことはできません。これにより、すべての一時ファイルが削除されます。

+0

そう呼び出します_閉じる?猿のパッチがなければ私はその一時ファイルにアクセスすることができない、と私は思う。 –

+0

私は今問題を見る。私は答えにいくつかの情報を追加しました、うまくいけばそれはあなたのために働くでしょう。 – Guss

+0

ありがとう! GCを明示的に呼び出すと問題が解決するとは思いません。私のテストでは、一時ファイルをクリーンアップしないようにする唯一の方法は、プログラムを中断することです。だから私は何が起こっているのか理解できません。 –

1

間違いなくバグではありませんが、IOの処理にはエラーがあります。 Buffer.ioは、@sizeが10240バイト未満の場合はStringIO、それ以上の場合はTempfileです。 OpenURI.open_uri()の確実な句はclose()を呼び出していますが、close!()メソッドを持たないStringIOオブジェクトである可能性があるため、単にclose()を呼び出すことはできません。

修正、私が思うに、これらのいずれかのようになります。

クラスの句のチェックを確保し、StringIO.closeまたはTempfile.closeのいずれかを呼び出します!必要に応じて。

- または -

バッファクラスは、クラスのチェックを処理し、正しいメソッドを呼び出すファイナライザを必要とします。

IOを処理するためにブロックを使用しないと問題は解決しませんが、open()はバッファではなくIOオブジェクトを返すので、独自のチェックを行うことができます。オブジェクト。

libは面倒なコードimhoの大きなチャンクです。そのため、work-overを使用してクリーンアップすることができます。私はそれを楽しむことができると思う。 ^。^

+0

SynTruth、私は考えていますが、ダックタイピング言語では、クラスをチェックしてください。メソッドに応答するかどうかをチェックします:)。とにかく、私はあなたがそれを修正したかどうかわからないので、今この問題から遠いです。しかし、もしあなたが好きなら、ちょうど好奇心のために、報告してください。 –

4

をあなたが本当にあなたは、一時ファイルを使用しないopen-uriを強制したい場合はできOpenURI::Buffer::StringMax定数と混乱:

> require 'open-uri' 
=> true 
> OpenURI::Buffer::StringMax 
=> 10240 
> open("http://www.yahoo.com") 
=> #<File:/tmp/open-uri20110111-16395-8vco29-0> 
> OpenURI::Buffer::StringMax = 1_000_000_000_000 
(irb):10: warning: already initialized constant StringMax 
=> 1000000000000 
> open("http://www.yahoo.com") 
=> #<StringIO:0x6f5b1c> 

ためopen-uri.rbからこのスニペットのだ:

class Buffer 
    [...] 
    StringMax = 10240 
    def <<(str) 
    [...] 
    if [...] StringMax < @size 
     require 'tempfile' 
関連する問題