mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Clarify how a service can build other composed services
* Service.build takes the literal YAML config hash for the service and a reference to the Configurator that's doing the building. * Services that compose additional services can use the Configurator to look them up and build them by name. See MirrorService for an example. References #23
This commit is contained in:
parent
1a17cfb9d9
commit
4d292fc0e7
5 changed files with 39 additions and 38 deletions
|
@ -32,15 +32,24 @@
|
|||
class ActiveStorage::Service
|
||||
class ActiveStorage::IntegrityError < StandardError; end
|
||||
|
||||
extend ActiveSupport::Autoload
|
||||
autoload :Configurator
|
||||
|
||||
# Configure an Active Storage service by name from a set of configurations,
|
||||
# typically loaded from a YAML file. The Active Storage engine uses this
|
||||
# to set the global Active Storage service when the app boots.
|
||||
def self.configure(service_name, configurations)
|
||||
require 'active_storage/service/configurator'
|
||||
Configurator.new(service_name, configurations).build
|
||||
Configurator.build(service_name, configurations)
|
||||
end
|
||||
|
||||
# Override in subclasses that stitch together multiple services and hence
|
||||
# need to do additional lookups from configurations. See MirrorService.
|
||||
def self.build(service_config, all_configurations) #:nodoc:
|
||||
new(service_config)
|
||||
# need to build additional services using the configurator.
|
||||
#
|
||||
# Passes the configurator and all of the service's config as keyword args.
|
||||
#
|
||||
# See MirrorService for an example.
|
||||
def self.build(configurator:, service: nil, **service_config) #:nodoc:
|
||||
new(**service_config)
|
||||
end
|
||||
|
||||
def upload(key, io, checksum: nil)
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
class ActiveStorage::Service::Configurator #:nodoc:
|
||||
def initialize(service_name, configurations)
|
||||
@service_name, @configurations = service_name.to_sym, configurations.symbolize_keys
|
||||
attr_reader :configurations
|
||||
|
||||
def self.build(service_name, configurations)
|
||||
new(configurations).build(service_name)
|
||||
end
|
||||
|
||||
def build
|
||||
service_class.build(service_config.except(:service), @configurations)
|
||||
def initialize(configurations)
|
||||
@configurations = configurations.symbolize_keys
|
||||
end
|
||||
|
||||
def build(service_name)
|
||||
config = config_for(service_name.to_sym)
|
||||
resolve(config.fetch(:service)).build(**config, configurator: self)
|
||||
end
|
||||
|
||||
private
|
||||
def service_class
|
||||
resolve service_class_name
|
||||
end
|
||||
|
||||
def service_class_name
|
||||
service_config.fetch :service do
|
||||
raise "Missing Active Storage `service: …` configuration for #{service_config.inspect}"
|
||||
def config_for(name)
|
||||
configurations.fetch name do
|
||||
raise "Missing configuration for the #{name.inspect} Active Storage service. Configurations available for #{configurations.keys.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
def service_config
|
||||
@configurations.fetch @service_name do
|
||||
raise "Missing configuration for the #{@service_name.inspect} Active Storage service. Configurations available for #{@configurations.keys.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
def resolve(service_class_name)
|
||||
require "active_storage/service/#{service_class_name.to_s.downcase}_service"
|
||||
ActiveStorage::Service.const_get(:"#{service_class_name}Service")
|
||||
def resolve(class_name)
|
||||
require "active_storage/service/#{class_name.to_s.downcase}_service"
|
||||
ActiveStorage::Service.const_get(:"#{class_name}Service")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,15 +5,11 @@ class ActiveStorage::Service::MirrorService < ActiveStorage::Service
|
|||
|
||||
delegate :download, :exist?, :url, to: :primary
|
||||
|
||||
# Stitch together from named configuration.
|
||||
def self.build(service_config, all_configurations) #:nodoc:
|
||||
primary = ActiveStorage::Service.configure(service_config.fetch(:primary), all_configurations)
|
||||
|
||||
mirrors = service_config.fetch(:mirrors).collect do |service_name|
|
||||
ActiveStorage::Service.configure(service_name.to_sym, all_configurations)
|
||||
end
|
||||
|
||||
new primary: primary, mirrors: mirrors
|
||||
# Stitch together from named services.
|
||||
def self.build(primary:, mirrors:, configurator:, **options) #:nodoc:
|
||||
new \
|
||||
primary: configurator.build(primary),
|
||||
mirrors: mirrors.collect { |name| configurator.build name }
|
||||
end
|
||||
|
||||
def initialize(primary:, mirrors:)
|
||||
|
|
|
@ -2,7 +2,7 @@ require "tmpdir"
|
|||
require "service/shared_service_tests"
|
||||
|
||||
class ActiveStorage::Service::DiskServiceTest < ActiveSupport::TestCase
|
||||
SERVICE = ActiveStorage::Service.configure(:test, test: { service: "Disk", root: File.join(Dir.tmpdir, "active_storage") })
|
||||
SERVICE = ActiveStorage::Service::DiskService.new(root: File.join(Dir.tmpdir, "active_storage"))
|
||||
|
||||
include ActiveStorage::Service::SharedServiceTests
|
||||
end
|
||||
|
|
|
@ -5,9 +5,8 @@ require "active_support/testing/autorun"
|
|||
require "byebug"
|
||||
|
||||
require "active_storage"
|
||||
|
||||
require "active_storage/service"
|
||||
ActiveStorage::Blob.service = ActiveStorage::Service.configure(:test, test: { service: 'Disk', root: File.join(Dir.tmpdir, "active_storage") })
|
||||
require "active_storage/service/disk_service"
|
||||
ActiveStorage::Blob.service = ActiveStorage::Service::DiskService.new(root: File.join(Dir.tmpdir, "active_storage"))
|
||||
|
||||
require "active_storage/verified_key_with_expiration"
|
||||
ActiveStorage::VerifiedKeyWithExpiration.verifier = ActiveSupport::MessageVerifier.new("Testing")
|
||||
|
|
Loading…
Reference in a new issue