如何从Resque工作者向客户端发送数据?

时间:2013-06-25 03:53:40

标签: ruby-on-rails postgresql heroku resque

我在Heroku上运行了一个rails应用程序。我正在尝试添加一项功能,允许用户以CSV格式下载部分数据。 CSV文件很大(约1-2 MB),生成起来很慢。为了不占用我的网络动态,我将这些下载请求传递给工作人员dynos(使用Resque),并在那里组装CSV。我的resque工作人员看起来像这样。

class Downloader

  def self.perform(ids_to_download)
      models = Model.where(:id => ids_to_download)
      csv_data_for_client = models.to_csv 
  end

end

我想知道将csv文件发送回请求它的客户端的最佳方法。

如果此代码位于Rails控制器中,则可以使用send_data csv_data_for_client完成此操作。但是,这种方法似乎并不适用于Resque工作者。

通过研究SO和互联网上的其他地方,似乎我有一些选择。

  1. 直接从Resque工作人员发送数据(虽然我不确定这是否可行)
  2. 将数据保存到heroku文件系统,在控制器中检索它,然后使用send_data
  3. 发送它
  4. 将其保存到数据库(postgresql),在控制器中检索它,然后使用send_data
  5. 有人可以就最佳方式提供建议吗?感谢。

1 个答案:

答案 0 :(得分:1)

在做了一些思考后,我删除了选项1和2.

Re 1,我无法弄清楚如何从Resque工作者直接将csv文件发送到客户端。

Re 2,将csv文件保存到Heroku似乎也不可行。 Heroku的文档说each dyno has its own filesystem,这个文件系统只对拥有它的dyno可见。我的工作人员dyno无法读取或写入我的web dyno的文件系统,反之亦然。所以这似乎也不是一个很有希望的选择。

这给了我选项3,将csv文件保存到我的worker dyno中的数据库中,然后检索它并将其发送到我的web dyno中的客户端。

我使用resque-status gem为每个csv文件请求分配唯一ID(uuid)。

我创建了一个简单的Model来保存生成的csv文件,并将其与uuid相关联。

class DownloaderJobOutput < ActiveRecord::Base
  attr_accessible :file_to_download, :uuid
end

在我的resque工作者中,在构建csv文件后,我将其保存到我的数据库中。

class Downloader
  @queue = :trial_downloader_queue
  include Resque::Plugins::Status

  def perform
    models = Model.where(:id => options["trial_ids"])
    csv = models.to_csv
    DownloaderJobOutput.create!( :uuid => self.uuid, :file_to_download => csv )
  end
end

当作业正在执行时,我从我的网络客户端查询它以跟踪其状态。完成后,我将其从数据库中取出并发送给客户端。