Ruby on rails 下载大型CSV文件作为后台进程时排队请求(延迟作业)
这在我的控制器中运行良好Ruby on rails 下载大型CSV文件作为后台进程时排队请求(延迟作业),ruby-on-rails,csv,delayed-job,Ruby On Rails,Csv,Delayed Job,这在我的控制器中运行良好 def export_list_sites_as_csv require "csv" csv_string = CSV.generate do |csv| csv << ["id","name", 'etc'] @search.relation.not_archived.each do |site| csv << [site.id, site.name, site.etc] en
def export_list_sites_as_csv
require "csv"
csv_string = CSV.generate do |csv|
csv << ["id","name", 'etc']
@search.relation.not_archived.each do |site|
csv << [site.id, site.name, site.etc]
end
end
send_data csv_string,
:type => 'text/csv',
:filename => '_sites.csv',
:disposition => 'attachment'
end
如何在自定义类中使用ActionController::Streaming
,或Model
编辑:
了解同步以及我如何处理这种情况
回答:你试图做的事违背了推迟工作的目的。 当用户发出请求时,服务器应做出响应以完成请求。问题是,有些请求需要相当长的时间才能完成,用户必须等待,直到完成。这是一个典型的案例——大量的电子邮件发送,但正如您所提到的,还有其他一些,比如数据套件生成。无论什么完成这项任务所需的时间比用户等待所需的时间还要长 现在来了一个被耽搁的工作。它在没有查询上下文的情况下执行特定的操作。不必着急。但是你不能只为它点击
send\u data
:它将不会有任何查询需要响应。相反,它应该将完成工作的结果写入一些持久性存储中
你有很多方法可以做到这一点
- 当数据集准备就绪时,您可以通过电子邮件通知用户。您甚至可以将其附加到电子邮件中,但我不推荐这样做:您不能依赖电子邮件提供商随时准备接受大量数据。创建用于下载数据集的链接,然后发送数据集。
- DelayedJob需要呈现数据集,将其保存到文件中,获取链接并通过电子邮件发送给用户
- 为你的应用程序制作一个听起来像“已完成的请求”的部分(模型、控制器和视图的公司),这可能是用户档案的一部分。“启动”请求应该指示用户稍后返回并查看该列表以获得结果。
- DelayedJob必须在请求完成后在该列表中输入一个条目。数据集的存储方式无关紧要,但您可以将其与上面的方法结合起来,将其保存到文件中并显示指向它的链接
send_data
这是一种仅在ActionController::Streaming
中可用的方法。那么有什么方法可以解决这个问题呢?或者调用此方法上的延迟作业。我认为,您可以这样做,在模型中调用csv生成的部分,然后在控制器中调用该方法,然后将结果变量和send_数据放在同一控制器中。@amtest smart soln,将尝试并写回。我不确定您试图实现什么。DelayedJob用于在请求-响应链之外执行作业,以避免延迟响应。DelayedJob很有可能将数据发送到任何地方,更可能是出现错误。如果您打算生成一个可下载的文件,那么应该让DelayedJob生成一个知道它指向的文件的模型实例,并让用户在完成后下载它。否则,如果您不介意生成延迟,那么使用DelayedJob是没有意义的。
class ExportCsv < Struct(:site_ids, :user_id)
def perform
require "csv"
sites = Site.where(id: site_ids)
CSV.open("tmp/#{user_id}.csv", "w+") do |csv|
csv << ["id","name", 'etc']
sites.each do |site|
csv << ....
end
end
end
def after(job)
send_file(
....
)
end
end