2014-01-13 134 views
2

我測試了這個簡單的作業,由普通的resque worker執行。由resque worker創建的臨時文件不會被刪除

class Jobs::TestTempfile 
    @queue = :test 

    def self.perform 
    Tempfile.open('foo') do |f| 
     puts f.path 
    end 
    end 
end 

創建的臨時文件仍保留在作業結束後,甚至一度工人已經終止(kill -QUIT pid)。

我知道最好的做法是取消鏈接並關閉所有Tempfiles,但這似乎是一個問題無論如何...是否有人意識到這一點的全球解決方案?或者我必須通過所有現有的作業手動取消鏈接Tempfiles

我使用ruby 2.1進行了測試(但我肯定存在的問題是2.0)和resque 1.24.1

謝謝!

回答

0

文件= Tempfile.new( '富')提出file.path

的工作方式相同,並刪除一次解釋退出的臨時文件。

+0

我不以Resque工人工作。我用你的語法測試了我的Job,輸出結果是一樣的。 – Such

+0

即使在殺死worker後,臨時文件仍然存在? – Giannis

+0

是的,即使在工人死亡後! – Such

0

從我的GitHub的答案複製這樣的:

閱讀視爲檔案文件:

當垃圾收集將它視爲對象,或當Ruby解釋器退出時,其關聯的臨時文件 自動刪除。這意味着在使用後沒有必要明確地刪除一個Tempfile文件,雖然 的做法很好:不明確地刪除未使用的Tempfiles文件系統可能會在文件系統上留下大量臨時文件,直到它們被垃圾收集爲止。這些臨時文件的存在可能會使難以確定新的臨時文件文件名稱 。

GC可能永遠不會在工作人員生命週期中運行,這會使所有臨時文件都保留在那裏。在::perform方法的末尾解除鏈接可能是最佳做法。

你也可以這樣做:

class JobWithTempfiles 
    class << self 

    def new_tmpfile(name) 
     file = Tempfile.new(name) 
     @tmp_files ||= [] 
     @tmp_files << file 
    end 

    def perform_with_tmpfile_cleanup 
     begin 
     perform_without_tmpfile_cleanup 
     ensure 
     @tmp_files.each do |tmpfile| 
      tmpfile.close 
      tmpfile.unlink 
     end 
     end 
    end 
    alias_method_chain :perform, :tmpfile_cleanup 
    end 
end 

class JobNeedingATmpFil < JobWithTempfiles 
    def self.perform_without_tempfile_cleanup 
    tmp_file = new_tmpfile("foo") 
    # Do a bunch of stuff 
    end 
end