我在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和互联网上的其他地方,似乎我有一些选择。
send_data
send_data
有人可以就最佳方式提供建议吗?感谢。
答案 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
当作业正在执行时,我从我的网络客户端查询它以跟踪其状态。完成后,我将其从数据库中取出并发送给客户端。