#primary (readonly)
[ GitHub ]# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 15
attr_reader :primary, :mirrors
123456789_123456789_123456789_123456789_123456789_
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
Service
|
|
|
Instance Chain:
self,
Service
|
|
| Inherits: |
Service
|
| Defined in: | activestorage/lib/active_storage/service/mirror_service.rb |
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:
Stitch together from named services.
Delete the file at the key on all services.
Delete files at keys starting with the prefix on all services.
Copy the file at the key from the primary service to each of the mirrors where it doesn't already exist.
Upload the io to the key specified to all services.
MirrorService
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 30
def initialize(primary:, mirrors:) @primary, @mirrors = primary, mirrors @executor = Concurrent::ThreadPoolExecutor.new( name: "ActiveStorage-mirror-service", min_threads: 1, max_threads: mirrors.size, max_queue: 0, fallback_policy: :caller_runs, idle_time: 60 ) end
Stitch together from named services.
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 21
def self.build(primary:, mirrors:, name:, configurator:, **) # :nodoc: new( primary: configurator.build(primary), mirrors: mirrors.collect { |mirror_name| configurator.build mirror_name } ).tap do |service_instance| service_instance.name = name end end
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 15
attr_reader :primary, :mirrors
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 15
attr_reader :primary, :mirrors
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
Delete the file at the key on all services.
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 52
def delete(key) perform_across_services :delete, key end
Delete files at keys starting with the prefix on all services.
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 57
def delete_prefixed(prefix) perform_across_services :delete_prefixed, prefix end
Boolean
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 17
delegate :download, :download_chunk, :exist?, :url, :url_for_direct_upload, :headers_for_direct_upload, :path_for, :compose, to: :primary
Copy the file at the key from the primary service to each of the mirrors where it doesn't already exist.
# 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
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 61
def mirror_later(key, checksum:) # :nodoc: ActiveStorage::MirrorJob.perform_later key, checksum: checksum end
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 84
def perform_across_services(method, *args) tasks = each_service.collect do |service| Concurrent::Promise.execute(executor: @executor) do service.public_send method, *args end end tasks.each(&:value!) end
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.
# File 'activestorage/lib/active_storage/service/mirror_service.rb', line 45
def upload(key, io, checksum: nil, **) io.rewind primary.upload key, io, checksum: checksum, ** mirror_later key, checksum: checksum end