在我的Rails应用中,user
每月最多可以创建3000 invoices
。他/她还可以为每张发票生成发票PDF。这是即时发生的,即PDF永远不会保存在服务器上的任何位置。
我希望我的用户能够将all发票PDF作为单个ZIP文件下载。
我在当前解决方案中使用Prawn PDF和ZIP tricks gem:
class InvoicesController < ApplicationController
def index
invoices = current_user.invoices
respond_to do |format|
format.zip do
DownloadInvoiceArchive.call(invoices, response, view_context)
end
end
end
end
class DownloadInvoiceArchive
include ActionController::Live
LIMIT = 100
def self.call(invoices, response, view_context)
zipname = "invoices.zip"
disposition = "attachment; filename=\"#{zipname}\""
response.headers["Content-Disposition"] = disposition
response.headers["Content-Type"] = "application/zip"
response.headers["Last-Modified"] = Time.now.httpdate.to_s
response.headers["X-Accel-Buffering"] = "no"
writer = ZipTricks::BlockWrite.new do |chunk|
response.stream.write(chunk)
end
ZipTricks::Streamer.open(writer) do |zip|
invoices.each_with_index do |invoice, index|
break if index == LIMIT
file_name = "#{invoice.number}.pdf"
zip.write_deflated_file(file_name) do |file_writer|
pdf = InvoicePdf.new(invoice, view_context)
file_writer << pdf.render
end
end
end
response.stream.close
end
end
但是,这种方法的性能非常差,因为它需要花费大量的时间来遍历数千张发票并为每张发票生成一个PDF。 (生成一个PDF会单独创建至少5个SQL查询。)
所以我的问题是如何在此处改善性能。
[一种选择是在后台作业中运行PDF生成,然后在准备就绪时通过电子邮件将下载链接发送给用户。但是应该将ZIP文件存储在哪里?在服务器的文件系统中还是在Amazon S3上?数据高度机密,下载后必须删除。
那么最好的方法是什么?感谢您的指导。
如果太长而无法在HTTP请求中处理,则必须将其移至后台作业。通过将生成的发票保存在服务器上,可以使其更快地运行,无论如何,BTW听起来还是个好主意,因为在许多国家/地区,发票必须以“不可更改的”数据格式存储。如果您的数据库与发票位于同一台服务器上,则可能不会引起任何重大的安全问题。
您是否没有保存它们的atm的特殊原因?