2013-08-23 49 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

相关问题