2013-08-23 81 views
6

在Rails中創建一個對象時,我想從asset目錄自動分配一個股票圖像,以供用戶稍後覆蓋。「Errno :: EMFILE:太多打開的文件」與創建本地圖像

結果,我在創建該對象的執行下面的私有方法:

def save_stock_image 
    image_path = Dir.glob(<list-of-images-from-directory>).sample 

    File.open(image_path) do |file| 
    self.image = file 
    self.save! 
    end 
end 

然而,經過6次RSpec的測試後,就開始收到以下錯誤:

Failure/Error: let(:object) { create(:object) } 
Errno::EMFILE: 
    Too many open files - /tmp/16020130822-36578-q8j9v9.jpg 
# ./app/models/object.rb:502:in `block in save_stock_image' 
# ./app/models/object.rb:501:in `open' 
# ./app/models/object.rb:501:in `save_stock_image' 
# ./spec/controllers/object_controller_spec.rb:318:in `block (3 levels) in <top (required)>' 
# ./spec/controllers/object_controller_spec.rb:344:in `block (4 levels) in <top (required)>' 

的以上錯誤在60次測試中有40次。我已經看過幾個SO問題,以及https://github.com/thoughtbot/paperclip/issues/1122https://github.com/thoughtbot/paperclip/issues/1000。我能找到的最接近的答案是確保文件描述符關閉。在我在塊中使用File.open之前,我明確地用file.close關閉了文件 - 這也不起作用。

顯而易見,我做錯了什麼?有沒有更好的方法來完成我想要做的事情?

UPDATE

它看起來有事情做與回形針創建它們上傳到S3前的臨時文件。有沒有關閉我失蹤的那些臨時文件?

回答

0

如果這是一個開發/測試環境,你想有一個快速的解決方案。

嘗試識別resque進程ID,殺死它並重新啓動resque服務器。

此外,你可以嘗試以下

Redis.current.client.reconnect 
$redis = Redis.current 
0

恰好碰到了這一點,並在最新的代碼並沒有幫助我的。所以,我通過生成一個子進程委託這些臨時文件在關閉到OS的工作:

def save_stock_image 
    ActiveRecord::Base.connection.disconnect! 
    Proces.fork do 
    image_path = Dir.glob(<list-of-images-from-directory>).sample 

    File.open(image_path) do |file| 
     self.image = file 
     self.save! 
    end 
    end 
    Process.wait  
    ActiveRecord::Base.establish_connection 
end 

此外,考慮將在Process.wait超時喜歡這裏建議:Waiting for Ruby child pid to exit

相關問題