使用Sidekiq将文件下载到后台进程中

时间:2013-11-25 16:14:03

标签: ruby-on-rails ruby-on-rails-3 download resque worker

我正在尝试将文件下载分解为后台进程。我的资产存储在S3上。

我的原始(阻止)代码看起来像这样

# From DownloadsController#download

data = open(path)
send_data(data.read, type: @download.mime_type, filename: @download.file_title)

所以我设置了Redis和Sidekiq,并创建了FielDownloadWorker

class FileDownloadWorker

  include Sidekiq::Worker

  def perform(path, mime_type, file_title)
    data = open(path)
    # What happens next?
  end

end

使用以下方式调用:

FileDownloadWorker.perform_async(path,@ download.mime_type,@ download.file_title)

如何从工作人员开始下载?

2 个答案:

答案 0 :(得分:4)

你做不到。您希望用户收到该文件,对吗?它必须在控制器内发生,以便控制器可以响应下载。如果您正在尝试实现并发性,请尝试使用线程:

@data = nil
t = Thread.new { @data = open(path) }
# ... do other stuff ...
t.join # wait for download to finish in other thread
send_data(@data.read, type: @download.mime_type, filename: @download.file_title)

如果您决定采用工作方法,则可以在下载完成后更新数据库字段或缓存,然后用户必须向您的应用程序发出另一个请求以获取完成的文件。类似的东西:

  1. 用户点击按钮开始下载。
  2. 页面更新,并显示消息“您的文件正在下载,请在几秒钟内刷新页面”
  3. 用户刷新页面,您的控制器会看到该文件已下载并执行send_data

答案 1 :(得分:0)

我最终使用Query String Authentication直接从S3启动文件下载。这样,文件就会从S3直接下载到客户端,并且Rails应用程序的线程也不会被阻止。

精彩的文章here