aboutsummaryrefslogtreecommitdiffstats
path: root/lib/active_storage/service/mirror_service.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2017-07-24 08:48:42 -0500
committerDavid Heinemeier Hansson <david@loudthinking.com>2017-07-24 08:48:42 -0500
commit69922fc7154fb0b99031b3215f42bb0124715608 (patch)
treedfa246ca0ef21c2abfe16b485db6881339dc4d15 /lib/active_storage/service/mirror_service.rb
parentb2032888194ded868d22993c720ea1b03c4f754b (diff)
downloadrails-69922fc7154fb0b99031b3215f42bb0124715608.tar.gz
rails-69922fc7154fb0b99031b3215f42bb0124715608.tar.bz2
rails-69922fc7154fb0b99031b3215f42bb0124715608.zip
Everything under app/ is eager loaded, don't want that for service
Since it references all the specific cloud services that are intended only to be loaded on demand.
Diffstat (limited to 'lib/active_storage/service/mirror_service.rb')
-rw-r--r--lib/active_storage/service/mirror_service.rb40
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/active_storage/service/mirror_service.rb b/lib/active_storage/service/mirror_service.rb
new file mode 100644
index 0000000000..54465cad05
--- /dev/null
+++ b/lib/active_storage/service/mirror_service.rb
@@ -0,0 +1,40 @@
+require "active_support/core_ext/module/delegation"
+
+class ActiveStorage::Service::MirrorService < ActiveStorage::Service
+ attr_reader :primary, :mirrors
+
+ delegate :download, :exist?, :url, to: :primary
+
+ # 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:)
+ @primary, @mirrors = primary, mirrors
+ end
+
+ def upload(key, io, checksum: nil)
+ each_service.collect do |service|
+ service.upload key, io.tap(&:rewind), checksum: checksum
+ end
+ end
+
+ def delete(key)
+ perform_across_services :delete, key
+ end
+
+ private
+ def each_service(&block)
+ [ primary, *mirrors ].each(&block)
+ end
+
+ def perform_across_services(method, *args)
+ # FIXME: Convert to be threaded
+ each_service.collect do |service|
+ service.public_send method, *args
+ end
+ end
+end