123456789_123456789_123456789_123456789_123456789_

Class: ActiveStorage::Service::MirrorService

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: ActiveStorage::Service
Defined in: activestorage/lib/active_storage/service/mirror_service.rb

Overview

Active Storage Mirror Service

Wraps a set of mirror services and provides a single ::ActiveStorage::Service object that will all have the files uploaded to them. A #primary service is designated to answer calls to:

Class Method Summary

::ActiveStorage::Service - Inherited

.configure

Configure an Active Storage service by name from a set of configurations, typically loaded from a YAML file.

::ActiveSupport::Autoload - Extended

Instance Attribute Summary

Instance Method Summary

::ActiveStorage::Service - Inherited

#compose

Concatenate multiple files into a single “composed” file.

#delete

Delete the file at the key.

#delete_prefixed

Delete files at keys starting with the prefix.

#download

Return the content of the file at the key.

#download_chunk

Return the partial content in the byte range of the file at the key.

#exist?

Return true if a file exists at the key.

#headers_for_direct_upload

Returns a ::Hash of headers for #url_for_direct_upload requests.

#open,
#update_metadata

Update metadata for the file identified by key in the service.

#upload

Upload the io to the key specified.

#url

Returns the URL for the file at the key.

#url_for_direct_upload

Returns a signed, temporary URL that a direct upload file can be PUT to on the key.

Constructor Details

.new(primary:, mirrors:) ⇒ MirrorService

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 31

def initialize(primary:, mirrors:)
  @primary, @mirrors = primary, mirrors
  @executor = Concurrent::ThreadPoolExecutor.new(
    min_threads: 1,
    max_threads: mirrors.size,
    max_queue: 0,
    fallback_policy: :caller_runs,
    idle_time: 60
  )
end

Instance Attribute Details

#compose (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#download (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#download_chunk (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#headers_for_direct_upload (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#mirrors (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 16

attr_reader :primary, :mirrors

#path_for (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#primary (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 16

attr_reader :primary, :mirrors

#url (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#url_for_direct_upload (readonly)

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

Instance Method Details

#delete(key)

Delete the file at the key on all services.

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 52

def delete(key)
  perform_across_services :delete, key
end

#delete_prefixed(prefix)

Delete files at keys starting with the prefix on all services.

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 57

def delete_prefixed(prefix)
  perform_across_services :delete_prefixed, prefix
end

#exist?Boolean

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 18

delegate :download, :download_chunk, :exist?, :url,
  :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary

#mirror(key, checksum:)

Copy the file at the key from the primary service to each of the mirrors where it doesn’t already exist.

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 66

def mirror(key, checksum:)
  instrument :mirror, key: key, checksum: checksum do
    if (mirrors_in_need_of_mirroring = mirrors.select { |service| !service.exist?(key) }).any?
      primary.open(key, checksum: checksum) do |io|
        mirrors_in_need_of_mirroring.each do |service|
          io.rewind
          service.upload key, io, checksum: checksum
        end
      end
    end
  end
end

#upload(key, io, checksum: nil, **options)

Upload the io to the key specified to all services. The upload to the primary service is done synchronously whereas the upload to the mirrors is done asynchronously. If a checksum is provided, all services will ensure a match when the upload has completed or raise an ::ActiveStorage::IntegrityError.

[ GitHub ]

  
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 45

def upload(key, io, checksum: nil, **options)
  io.rewind
  primary.upload key, io, checksum: checksum, **options
  mirror_later key, checksum: checksum
end