.koppie/config/initializers/riiif.rb in hyrax-5.0.0.rc2 vs .koppie/config/initializers/riiif.rb in hyrax-5.0.0.rc3
- old
+ new
@@ -29,5 +29,83 @@
Riiif.not_found_image = Rails.root.join('app', 'assets', 'images', 'us_404.svg')
Riiif.unauthorized_image = Rails.root.join('app', 'assets', 'images', 'us_404.svg')
Riiif::Engine.config.cache_duration = 1.day
end
+
+module Hyrax
+ # Adds file locking to Riiif::File
+ # @see RiiifFileResolver
+ class RiiifFile < Riiif::File
+ include ActiveSupport::Benchmarkable
+
+ attr_reader :id
+ def initialize(input_path, tempfile = nil, id:)
+ super(input_path, tempfile)
+ raise(ArgumentError, "must specify id") if id.blank?
+ @id = id
+ end
+
+ # Wrap extract in a read lock and benchmark it
+ def extract(transformation, image_info = nil)
+ Riiif::Image.file_resolver.file_locks[id].with_read_lock do
+ benchmark "RiiifFile extracted #{path} with #{transformation.to_params}", level: :debug do
+ super
+ end
+ end
+ end
+
+ private
+
+ def logger
+ Hyrax.logger
+ end
+ end
+
+ class RiiifFileResolver
+ include ActiveSupport::Benchmarkable
+
+ # @param [String] id from iiif manifest
+ # @return [Riiif::File]
+ def find(id)
+ path = nil
+ file_locks[id].with_write_lock do
+ path = build_path(id)
+ path = build_path(id, force: true) unless File.exist?(path) # Ensures the file is locally available
+ end
+ RiiifFile.new(path, id: id)
+ end
+
+ # tracks individual file locks
+ # @see RiiifFile
+ # @return [Concurrent::Map<Concurrent::ReadWriteLock>]
+ def file_locks
+ @file_locks ||= Concurrent::Map.new do |k, v|
+ k.compute_if_absent(v) { Concurrent::ReadWriteLock.new }
+ end
+ end
+
+ private
+
+ def build_path(id, force: false)
+ Riiif::Image.cache.fetch("riiif:" + Digest::MD5.hexdigest("path:#{id}"),
+ expires_in: Riiif::Image.expires_in,
+ force: force) do
+ load_file(id)
+ end
+ end
+
+ def load_file(id)
+ benchmark "RiiifFileResolver loaded #{id}", level: :debug do
+ fs_id = id.sub(/\A([^\/]*)\/.*/, '\1')
+ file_set = Hyrax.query_service.find_by(id: fs_id)
+ file_metadata = Hyrax.custom_queries.find_original_file(file_set: file_set)
+ file_metadata.file.disk_path.to_s # Stores a local copy in tmpdir
+ end
+ end
+
+ def logger
+ Hyrax.logger
+ end
+ end
+end
+