"Errno :: EMFILE: Too many open files" with local images when creating

When creating an object in Rails, I want to automatically assign it a stock image from the resource directory, which can be overwritten later by the user.

As a result, I create the following private method when creating the object:

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 

However, after 6 RSpec tests, I start getting the following error:

 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)>' 

The above error is on ~ 40 of 60 tests. I looked through several SO questions, as well as https://github.com/thoughtbot/paperclip/issues/1122 and https://github.com/thoughtbot/paperclip/issues/1000 . The closest answer I could find was to close the file descriptor. Before I used File.open in a block, I explicitly closed the file with file.close - this didn't work either.

Something obvious that I'm wrong? Is there a better way to accomplish what I'm trying to do?

UPDATE

This seems to have something to do with temporary files created by Paperclip before they are uploaded to S3. Is there something with closing those tempfiles that I am missing?

+6
source share
3 answers

Just stumbled upon it myself. It seems that the main branch has a fix. See my comments here:

https://github.com/thoughtbot/paperclip/issues/1326?source=cc

+1
source

If it is a development / testing environment and requires quick resolution.

Try to identify the resque process id, kill it and restart the resque server.

Alternatively, you can try below.

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

Just stumbled upon this and the last code didn't help me. So, I delegated the work of closing these temporary OS files by creating a child process:

 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 

Also, consider placing a timeout in Process.wait, as suggested here: Waiting for a pid file to exit for Ruby

0
source

Source: https://habr.com/ru/post/952328/


All Articles