How to setup a fallback mechanism to mirroring store?

Hi guys,

I recently faced an issue where when there’s an issue with the store service provider, I cannot boot my app up due to seahorse error and service not available error raised by the S3 gem.

I know that I can use the mirroring plugin to connect another store as a backup. But is there anyone here know how/where can I rescue the error, mount the backup store as the main store and main store as the backup store, and gradually sync between these two stores once the original main store is back up again?

Your app should ideally not be making S3 requests during initialization, I would first address that.

As for addressing your problem, you could use some type of a circuit breaker pattern that would determine when the S3 service is unavailable, and set the Shrine storage dynamically based on this information. For example:

class AvailableStorage
  def initialize(s3, backup)
    @s3   = s3
    @backup = backup
  end

  extend Forwardable
  delegate [:upload, :open, :exists?, :url, :presign, :delete, :delete_prefixed, :clear!] => :storage

  def storage
    if S3Service.available? # your logic for determining whether S3 is down
      @s3
    else
      @backup
    end
  end
end

storages = {
  s3_cache: Shrine::Storage::S3.new(...),
  s3_store: Shrine::Storage::S3.new(...),
  backup_cache: ...,
  backup_store: ...,
}

Shrine.storages = {
  cache: AvailableStorage.new(*storages.values_at(:s3_cache, :backup_cache)),
  store: AvailableStorage.new(*storages.values_at(:s3_store, :backup_store)),
  **storages,
}