Большой двоичный объект изображения ActiveStorage исчезает

В Rails 5.2.1 у меня есть ActiveStorage (5.2.1), настроенный для службы Disk.

У меня есть модель Pic:

class Pic < ApplicationRecord
  has_one_attached :image
end

Могу прикрепить изображения:

imgpath = "/tmp/images/..."
Pic.first.image.attach(io: File.open(imgpath), filename: imgpath)

Я хотел сделать это в чем-то вроде задачи Rake (но результат будет таким же, если сделать это из консоли Rails) для пакетной загрузки изображений, например:

pfs = Dir['testpics/*']
Pic.all.each { |pic|
  pf = pfs.shift
  pic.image.attach(io: File.open(pf), filename: pf)
}

Это работает без ошибок. Однако, как ни странно (по крайней мере для меня), некоторые изображения не имеют впоследствии соответствующего большого двоичного объекта, и запросы завершаются с ошибкой 500 Internal Server Error: Errno::ENOENT (No such file or directory @ rb_sysopen.

Проверка pic.image.attached? возвращает истину. Однако pic.image.download выдает исключение.

Еще более странно то, что вызов pic.image.download сразу после его прикрепления работает. 2 секунды спустя это не так.

Единственный способ узнать, правильно ли загружено изображение, - это подождать ~ 2 секунды после его прикрепления и затем попытаться загрузить. Если я продолжу повторять попытки прикрепления после ожидания 2 секунд и проверки, все ли в порядке, все изображения будут в порядке. Но очевидно, что это неправильно. :) Простое ожидание между вызовами присоединения не помогает, я должен проверять после ожидания, затем повторно подключаться, а затем проверять снова, пока все не будет в порядке - иногда нормально с первой попытки, иногда 10-й, но в конечном итоге преуспеет.

Это все на моем локальном диске, а не, например, временное хранилище в Heroku. Также я запускаю его на Ubuntu 18.04 (Bionic), но ничего не установлено, что должно удалять капли (т.е. без антивируса и т.п.). Я действительно думаю, что проблема внутренняя в ActiveStorage, или, может быть, в том, как я ее использую.

В чем дело? Куда деваются капли через несколько секунд, когда они уже были успешно загружены?

С сервисом S3 все нормально, блобы не пропадают.


person Gabor Lengyel    schedule 28.10.2018    source источник


Ответы (2)


Вау, я думаю, что понял это. Это не столько проблема с ActiveStorage, но я оставлю вопрос здесь на случай, если он может быть полезен и для кого-то другого.

Оказывается, проблема была в Dropbox. :)

Что происходит со стратегией Disk, ActiveStorage хранит идентификаторы из двух символов в каталоге storage/ - аналогично хешу. Они могут (и довольно часто бывает) различаться только регистром, например, есть каталог zu и Zu. Клиент Dropbox мешает этому: если все это находится в каталоге, который синхронизируется с Dropbox, эти каталоги будут переименованы, например, «Zu» станет «zu (Case Conflict)» (так что синхронизация Dropbox работает на разных платформах).

Конечно, капли больше не обнаруживаются, и все это происходит асинхронно, клиенту Dropbox нужно время, чтобы переименовать файлы, поэтому он некоторое время работает сразу после прикрепления изображения.

Итак, урок извлечен, ActiveStorage плохо работает с Dropbox.

person Gabor Lengyel    schedule 07.11.2018

Теперь ActiveStorage поддерживает DropboxService. Пожалуйста, следите за гемом activestorage-dropbox

ActiveStorage :: Service :: DropboxService

Оборачивает службу хранилища Dropbox как службу активного хранилища.

gem 'activestorage-dropbox'

Использование

Объявите сервис Dropbox в config / storage.yml

dropbox:
  service: Dropbox
  access_token: ""
config.active_storage.service = :dropbox

https://rubygems.org/gems/activestorage-dropbox

person codingnightmare    schedule 22.05.2019