Я использую EventMachine и EM-Synchrony на сервере REST API. Когда я получаю запрос POST с большим двоичным файлом в теле, я получаю его кусками, записывая эти куски в Tempfile, не блокируя реактор.
Затем, в какой-то момент, мне нужно прочитать этот файл порциями и записать эти порции в окончательный файл. Это работает, но блокирует реактор, как и ожидалось, и не может найти способ заставить его работать без блокировки.
Я вызываю эту функцию через некоторое время, передавая ей временный файл и новое имя файла:
def self.save(tmp_file, new_file)
tmp = File.open(tmp_file, "rb")
newf = File.open(new_file, "wb")
md5 = Digest::MD5.new
each_chunk(tmp, CHUNKSIZE) do |chunk|
newf << chunk
md5.update chunk
end
md5.hexdigest
end
def self.each_chunk(file, chunk_size=1024)
yield file.read(chunk_size) until file.eof?
end
Я читал все другие подобные вопросы здесь, в StackOverflow, пытаясь использовать EM # next_tick, что, возможно, является решением (не так много опыта EM), но не могу заставить его работать, возможно, я помещаю его в неправильные места.
Кроме того, я попробовал EM # defer, но мне нужна функция для ожидания завершения процесса чтения / записи, прежде чем он вернет md5, как в моем основном файле, после вызова этой функции я делаю обновление базы данных с возвращаемое значение.
Если кто-то может помочь мне в этом, я был бы благодарен.
РЕДАКТИРОВАТЬ 1
Мне нужно, чтобы функция сохранения возвращалась только после завершения чтения / записи файлов, так как в функции вызова я жду окончательного значения md5, что-то вроде этого:
def copy_and_update(...)
checksum = SomeModule.save(temp_file, new_file)
do_database_update({:checksum => checksum}) # only with the final md5 value
end