Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 下载大型CSV文件作为后台进程时排队请求(延迟作业)_Ruby On Rails_Csv_Delayed Job - Fatal编程技术网

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