我为用户提供了通过 CSV 下载大量数据的能力。为此,我正在使用 Sidekiq 并在他们启动后将任务放到后台作业中。我在后台工作中所做的是生成一个包含所有正确数据的 csv,将其存储在其中/tmp
,然后调用 save!在我的模型上,将文件的位置传递给回形针属性,然后该属性会关闭并存储在 S3 中。
所有这些在本地都运行良好。我现在的问题在于 Heroku,它能够根据您所在的节点在短时间内存储文件。由于 Heroku 处理这些文件的方式,我的后台作业无法找到保存的 tmp 文件。我想我正在寻找更好的方法来做到这一点。如果有某种方式可以在内存中完成所有事情,那就太棒了。唯一的问题是,当您保存模型时,回形针需要一个实际的文件对象作为属性。这是我的背景工作的样子:
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
为了便于阅读,我省略了查询方法。