Остановите Ruby on Rails от удаления многокомпонентных файлов стойки, созданных при загрузке - PullRequest
3 голосов
/ 09 ноября 2010

Когда файл загружается в Rails, он создает многокомпонентный файл стойки в папке / tmp.

RackMultipart20101109-31106-ylgoz0-0

После завершения запроса я использую delayed_job для первой обработки, а затем загружаю этот файл tmp в Amazon S3.

Проблема начинается, когда рельсы (или стойки) время от времени удаляют эти файлы при новой загрузке.

Мой сервер обрабатывает параллельные загрузки файлов размером от 1 до 1000 МБ, и довольно часто файл удаляется перед загрузкой на S3.

Есть ли способ предотвратить удаление этих файлов рельсами (или стойками)? Другие решения также приветствуются.

1 Ответ

2 голосов
/ 23 ноября 2010

Просто столкнулся с той же проблемой, и ответ на этот ТАК вопрос дает несколько подсказок.Самое главное:

Насколько я был в состоянии сказать или найти, нет физического файла, пока загрузка не будет прочитана.

Изначально у меня был кодстроки:

# In my controller:
Delayed::Job.enqueue(FileJob.new(params[:id], params[:upload].path))

# And In lib/file_job.rb
class FileJob < Struct.new(:file_id, :log_file) 
  def perform
    File.open(log_file)
    # Do important stuff with the incoming file.
  end
end

Итак, если мы только что переместили обработку нашего файла в delayed_job, а другой запрос поступил в до , то наш delayed_job сможет выполнить и прочитать файл... Фуф, наш файл кажется уничтоженным до того, как у него появилась возможность доступа, и поэтому физический файл не создается.

Мое решение этой проблемы заключается в следующем:

# In my controller:
FileUtils.copy_entry(params[:upload].path, params[:upload].path + "B")
Delayed::Job.enqueue(FileJob.new(params[:id], params[:upload].path + "B"))

# And In lib/file_job.rb
class FileJob < Struct.new(:file_id, :log_file) 
  def perform
    File.open(log_file)
    # Do important stuff with the incoming file.
    FileUtils.remove(log_file)
  end
end

Я немедленно скопировал файл в контроллер, который блокирует метод от другого входящего запроса.А затем я передаю новый путь в свой delayed_job, который, наконец, должен очистить скопированный файл после того, как он завершит работу с ним.

Это исправление, похоже, работает хорошо для меня, но я думаю, что вышеприведенное решение победилоне очень хорошо работает с очень большими файлами.Я хотел бы лучше понять, что происходит с рельсами и файлами, не существующими, пока они не будут прочитаны.

...