Отправка загруженного файла для восстановления работника для обработки - PullRequest
6 голосов
/ 08 августа 2011

Я только начал использовать resque, чтобы выполнить некоторую обработку некоторых очень больших файлов в фоновом режиме, и у меня возникают проблемы с выяснением, как передать файл работнику resque.Я использую rails для обработки загрузки файлов, и rails создает объект ActionDispatch::Http::UploadedFile для каждого файла, загруженного из формы.

Как отправить этот файл работнику resque?Я попытался отправить пользовательский хеш, содержащий только путь к временному файлу и исходное имя файла, но я больше не могу снова открыть временный файл в работнике resque (просто обычный Errno::ENOENT - No such file or directory), потому что rails, кажется, удаляет этот временный файл послезапрос заканчивается.

Ответы [ 2 ]

6 голосов
/ 08 августа 2011

Http::UploadedFile недоступен после завершения запроса. Вам нужно записать файл куда-нибудь (или использовать s3 в качестве временного хранилища). Передайте resque путь к файлу, который вы написали.

5 голосов
/ 09 ноября 2013

Я просто потратил два дня, пытаясь это сделать, и наконец понял это. Вам нужно кодировать Base64 файл, чтобы он мог быть сериализован в json. Затем вам нужно декодировать его в рабочий и создать новый

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)  

А вот как декодировать и преобразовать обратно в объект внутри вашего работника

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
...