ActiveStorage 图像 blob 消失
ActiveStorage image blob disappears
在 Rails 5.2.1 中,我为 Disk
服务配置了 ActiveStorage (5.2.1)。
我有一个图片模型:
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)
}
这运行没有错误。然而,令人惊讶的是(至少对我而言)一些 图像之后没有相应的 blob,并且查询失败并显示 500 Internal Server Error: Errno::ENOENT (No such file or directory @ rb_sysopen
.
检查 pic.image.attached?
returns 正确。但是,pic.image.download
抛出异常。
甚至是陌生人,在附加后立即调用 pic.image.download
确实 有效。 2 秒后它没有。
我能想到的判断图像是否正确上传的唯一方法是在附加图像后等待约 2 秒,然后然后 尝试下载。如果我在等待 2 秒后继续重试附加并检查是否正常,所有图像都会正常。但显然这不是正确的做法。 :) 只是在附加调用之间等待没有帮助,我必须在等待后检查,然后重新连接然后再次检查直到它没问题 - 有时第一次尝试就可以,有时第 10 次,但 最终 会成功的。
这一切都在我的本地磁盘上,而不是 Heroku 中的临时存储。另外我 运行 它在 Ubuntu 18.04 (Bionic) 上,没有安装任何应该删除 blob 的东西(即没有杀毒软件或类似软件)。我真的认为问题出在 ActiveStorage 内部,或者可能是我使用它的方式。
这是怎么回事? blob 几秒钟后会去哪里,当它们已经成功上传时?
使用 S3 服务一切正常,blob 不会消失。
哇,我想我明白了。这不是一个 ActiveStorage 问题,但我会把问题留在这里,以防它对其他人也有用。
原来问题可能出在 Dropbox 上。 :)
Disk
策略会发生什么,ActiveStorage 将两个字符的标识符存储在 storage/
目录中 - 类似于散列。这些可以(并且经常)碰巧只是大小写不同,例如有一个 zu
和一个 Zu
目录。 Dropbox 客户端干扰的方式是,如果所有这些都在与 Dropbox 同步的目录中,这些目录将被重命名,例如“Zu
”将变为“zu (Case Conflict)
”(所以Dropbox 同步跨平台工作)。
当然再也找不到 blob,而且这一切都是异步发生的,Dropbox 客户端需要一些时间来重命名内容,这就是为什么它在附加图像后立即工作一段时间的原因。
吸取教训,ActiveStorage 不能很好地与 Dropbox 配合使用。
现在,ActiveStorage 支持DropboxService。请关注activestorage-dropboxgem
ActiveStorage::Service::DropboxService
将 Dropbox 存储服务包装为活动存储服务。
gem 'activestorage-dropbox'
用法
在 config/storage.yml
中声明一个 Dropbox 服务
dropbox:
service: Dropbox
access_token: ""
config.active_storage.service = :dropbox
在 Rails 5.2.1 中,我为 Disk
服务配置了 ActiveStorage (5.2.1)。
我有一个图片模型:
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)
}
这运行没有错误。然而,令人惊讶的是(至少对我而言)一些 图像之后没有相应的 blob,并且查询失败并显示 500 Internal Server Error: Errno::ENOENT (No such file or directory @ rb_sysopen
.
检查 pic.image.attached?
returns 正确。但是,pic.image.download
抛出异常。
甚至是陌生人,在附加后立即调用 pic.image.download
确实 有效。 2 秒后它没有。
我能想到的判断图像是否正确上传的唯一方法是在附加图像后等待约 2 秒,然后然后 尝试下载。如果我在等待 2 秒后继续重试附加并检查是否正常,所有图像都会正常。但显然这不是正确的做法。 :) 只是在附加调用之间等待没有帮助,我必须在等待后检查,然后重新连接然后再次检查直到它没问题 - 有时第一次尝试就可以,有时第 10 次,但 最终 会成功的。
这一切都在我的本地磁盘上,而不是 Heroku 中的临时存储。另外我 运行 它在 Ubuntu 18.04 (Bionic) 上,没有安装任何应该删除 blob 的东西(即没有杀毒软件或类似软件)。我真的认为问题出在 ActiveStorage 内部,或者可能是我使用它的方式。
这是怎么回事? blob 几秒钟后会去哪里,当它们已经成功上传时?
使用 S3 服务一切正常,blob 不会消失。
哇,我想我明白了。这不是一个 ActiveStorage 问题,但我会把问题留在这里,以防它对其他人也有用。
原来问题可能出在 Dropbox 上。 :)
Disk
策略会发生什么,ActiveStorage 将两个字符的标识符存储在 storage/
目录中 - 类似于散列。这些可以(并且经常)碰巧只是大小写不同,例如有一个 zu
和一个 Zu
目录。 Dropbox 客户端干扰的方式是,如果所有这些都在与 Dropbox 同步的目录中,这些目录将被重命名,例如“Zu
”将变为“zu (Case Conflict)
”(所以Dropbox 同步跨平台工作)。
当然再也找不到 blob,而且这一切都是异步发生的,Dropbox 客户端需要一些时间来重命名内容,这就是为什么它在附加图像后立即工作一段时间的原因。
吸取教训,ActiveStorage 不能很好地与 Dropbox 配合使用。
现在,ActiveStorage 支持DropboxService。请关注activestorage-dropboxgem
ActiveStorage::Service::DropboxService
将 Dropbox 存储服务包装为活动存储服务。
gem 'activestorage-dropbox'
用法
在 config/storage.yml
中声明一个 Dropbox 服务dropbox:
service: Dropbox
access_token: ""
config.active_storage.service = :dropbox