Я использую EventMachine и EM-Synchrony на сервере API REST. Когда вы получаете запрос POST с большим двоичным файлом в теле, я получаю его в кусках, записывая эти фрагменты в Tempfile, не блокируя реактор.EventMachine чтение и запись файлов в кусках
Затем, в некоторый момент, мне нужно прочитать этот файл в кусках и записать эти фрагменты в окончательный файл. Это работает, но он блокирует реактор, как ожидалось, и не может найти способ заставить его работать без блокировки.
Я называю эту функцию в какой-то момент, передавая ему 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, как в моем основном файле, после вызова этой функции я делаю обновление базы данных с возвращаемым значением.
Если кто-то может мне помочь, я был бы благодарен.
EDIT 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
'new' - это имя метода класса. Поэтому, если это не модуль, это может быть одна ошибка. Измените его на что-то вроде 'new_file' и протестируйте его. – Linuxios
Whell, его только в этом примере кода, я не использую имена переменных. –
ОК. Я просто подумал, что это может быть проблемой, поскольку самые маленькие проблемы могут показаться самыми большими. – Linuxios