【问题标题】:Break Out File Download into Background Process Using Sidekiq使用 Sidekiq 将文件下载分解到后台进程
【发布时间】:2015-12-11 17:22:47
【问题描述】:

我正在尝试将文件下载拆分为后台进程。我的资产存储在 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)

如何从工作器启动下载?

【问题讨论】:

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


    【解决方案1】:

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

    @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

    【讨论】:

    • 感谢您的回复。我正在尝试做一个非标准的方法吗?我应该担心阻止下载吗?
    • 将阻塞 IO 操作推迟到工作人员是非常标准的。但让工作人员通过下载响应用户并不是标准的。工人不能做出回应。只有控制器可以。解决这个问题的一些方法是使用上述解决方案。
    【解决方案2】:

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

    很棒的文章here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-28
      • 2015-09-13
      • 2014-09-06
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多