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



我正试图将文件下载分解为后台进程。我的资产存储在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(路径,@download.mime_type,@download.file_title)

如何从工作人员启动下载

你不能。您希望用户接收该文件,对吗?它必须在控制器内发生,以便控制器能够通过下载来响应。如果您试图实现并发,请尝试使用线程:

@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)

如果你决定采用worker方法,你可以让它在下载完成时更新数据库字段或缓存,那么用户必须向你的应用程序发出另一个请求才能获得完成的文件。类似于:

  1. 用户单击按钮启动下载
  2. 页面更新消息"您的文件正在下载,几秒钟后刷新页面"
  3. 用户刷新页面,控制器看到文件已下载并执行send_data

我最终使用查询字符串身份验证直接从S3启动了文件下载。通过这种方式,文件从S3直接下载到客户端,Rails应用程序的线程不会被阻塞。

这里写得很棒。

最新更新