Я предоставляю пользователям возможность загружать чрезвычайно большие объемы данных через CSV. Для этого я использую Sidekiq и переношу задачу в фоновое задание, как только они ее инициируют. Что я сделал в фоновом задании, так это сгенерировал csv, содержащий все нужные данные, сохранил их в /tmp
, а затем вызвал save! на моей модели, передавая местоположение файла атрибуту скрепки, который затем отключается и сохраняется в S3.
Все это прекрасно работает локально. Теперь моя проблема связана с Heroku, и его способность хранить файлы в течение короткого времени зависит от того, на каком узле вы находитесь. Моя фоновая работа не может найти сохраненный файл tmp из-за того, как Heroku обрабатывает эти файлы. Думаю, я ищу лучший способ сделать это. Если есть какой-то способ сделать все в памяти, это было бы здорово. Единственная проблема заключается в том, что скрепка ожидает фактический файловый объект в качестве атрибута при сохранении модели. Вот как выглядит моя фоновая работа:
class CsvWorker
include Sidekiq::Worker
def perform(report_id)
puts "Starting the jobz!"
report = Report.find(report_id)
items = query_ranged_downloads(report.start_date, report.end_date)
csv = compile_csv(items)
update_report(report.id, csv)
end
def update_report(report_id, csv)
report = Report.find(report_id)
report.update_attributes(csv: csv, status: true)
report.save!
end
def compile_csv(items)
clean_items = items.compact
path = File.new("#{Rails.root}/tmp/uploads/downloads_by_title_#{Process.pid}.csv", "w")
csv_string = CSV.open(path, "w") do |csv|
csv << ["Item Name", "Parent", "Download Count"]
clean_items.each do |row|
if !row.item.nil? && !row.item.parent.nil?
csv << [
row.item.name,
row.item.parent.name,
row.download_count
]
end
end
end
return path
end
end
Я пропустил метод запроса для удобства чтения.