我正在尝试将文件下载分解为后台进程。我的资产存储在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)
如何从工作人员开始下载?
答案 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)
如果您决定采用工作方法,则可以在下载完成后更新数据库字段或缓存,然后用户必须向您的应用程序发出另一个请求以获取完成的文件。类似的东西:
send_data
答案 1 :(得分:0)
我最终使用Query String Authentication直接从S3启动文件下载。这样,文件就会从S3直接下载到客户端,并且Rails应用程序的线程也不会被阻止。
精彩的文章here。