将上传的文件发送给resque worker进行处理

Jon*_* C. 6 file-upload ruby-on-rails resque

我刚刚开始使用resque在后台对一些非常大的文件进行处理,而我却无法弄清楚如何将文件传递给resque worker.我使用rails来处理文件上传,rails ActionDispatch::Http::UploadedFile为从表单上传的每个文件创建一个对象.

如何将此文件发送给resque工作者?我尝试发送一个只有临时文件的路径名和原始文件名的自定义哈希,但我不能再重新打开resque worker中的临时文件(只是正常Errno::ENOENT - No such file or directory),因为rails似乎在请求结束后删除了该临时文件.

klo*_*ner 6

Http::UploadedFile请求完成后无法访问.您需要在某处编写文件(或使用s3作为临时存储).传递resque您编写的文件的路径.


小智 5

我花了两天时间试图做到这一点并最终弄明白了.您需要对文件进行Base64编码,以便将其序列化为json.然后你需要在worker中解码它并创建一个新的

ActionDispatch::Http::UploadedFile

以下是编码和传递给resque的方法:

// You only need to encode the actual file, everything else in the 
// ActionDispatch::Http::UploadedFile object is just string or a hash of strings

file = params[:file] // Your ActionDispatch::Http::UploadedFile object 
file.tempfile.binmode
file.tempfile = Base64.encode64(file.tempfile.read)

Resque.enqueue(QueueWorker, params)  
Run Code Online (Sandbox Code Playgroud)

以下是如何解码并转换回工作中的对象

class QueueWorker
    @queue = :main_queue

    def self.perform(params)
        file = params['file']
        tempfile = Tempfile.new('file')
        tempfile.binmode
        tempfile.write(Base64.decode64(file['tempfile']))

        // Now that the file is decoded you need to build a new
        // ActionDispatch::Http::UploadedFile with the decoded tempfile and the other
        // attritubes you passed in.

        file = ActionDispatch::Http::UploadedFile.new(tempfile: tempfile, filename: file['original_filename'], type: file['content_type'], head: file['headers'])

        // This object is now the same as the one in your controller in params[:file]
    end
end
Run Code Online (Sandbox Code Playgroud)

  • 我不建议这样做,除非你确定你的文件永远不会超过几百KB.将文件写入磁盘/ s3/etc并将该路径传递给Resque作业是处理此问题的正确方法. (4认同)