Mirroring
The mirroring plugin enables replicating uploads and deletes to
other storages. This can be useful for setting up a backup storage, or when
migrating files from one storage to another.
Shrine.plugin :mirroring, mirror: { store: :other_store }With the above setup, any upload and delete to :store will be replicated to
:other_store.
file = Shrine.upload(io, :store) # uploads to :store and :other_store
file.delete # deletes from :store and :other_storeYou can skip mirroring for a specific upload/delete call by passing mirror:
false:
file = Shrine.upload(io, :store, mirror: false) # skips mirroring
file.delete(mirror: false) # skips mirroringMultiple storages
You can mirror to multiple storages by specifying an array:
Shrine.plugin :mirroring, mirror: {
store: [:other_store_1, :other_store_2]
}Backup storage
If you want the mirror storage to act as a backup, you can disable mirroring deletes:
Shrine.plugin :mirroring, mirror: { ... }, delete: falseBackgrounding
You can have mirroring performed in a background job:
Shrine.mirror_upload_block do |file, **options|
MirrorUploadJob.perform_async(file.shrine_class.name, file.data)
end
Shrine.mirror_delete_block do |file|
MirrorDeleteJob.perform_async(file.shrine_class.name, file.data)
endclass MirrorUploadJob
include Sidekiq::Worker
def perform(shrine_class, file_data)
shrine_class = Object.const_get(shrine_class)
file = shrine_class.uploaded_file(file_data)
file.mirror_upload
end
endclass MirrorDeleteJob
include Sidekiq::Worker
def perform(shrine_class, file_data)
shrine_class = Object.const_get(shrine_class)
file = shrine_class.uploaded_file(file_data)
file.mirror_delete
end
endAPI
You can disable automatic mirroring and perform mirroring manually:
# disable automatic mirroring of uploads and deletes
Shrine.plugin :mirroring, mirror: { ... }, upload: false, delete: falseTo perform mirroring, you can call UploadedFile#mirror_upload and
UploadedFile#mirror_delete:
file = Shrine.upload(io, :store) # upload to :store
file.mirror_upload # upload to :other_store
file.delete # delete from :store
file.mirror_delete # delete from :other_storeIf you've set up backgrounding, you can use
UploadedFile#mirror_upload_background and
UploadedFile#mirror_delete_background to call the background block instead:
file = Shrine.upload(io, :store) # upload to :store
file.mirror_upload_background # spawn mirror upload background job
file.delete # delete from :store
file.mirror_delete_background # spawn mirror delete background job