class Longleaf::ServiceClassCache
Cache for loading and retrieving preservation service classes
Constants
- STD_PRESERVATION_SERVICE_PATH
Public Class Methods
new(app_manager)
click to toggle source
# File lib/longleaf/services/service_class_cache.rb, line 8 def initialize(app_manager) @app_manager = app_manager # Cache storing per service definition instances of service classes @service_instance_cache = Hash.new # Cache storing per script path class of service @class_cache = Hash.new end
Public Instance Methods
service_class(service_def)
click to toggle source
Load and return the PreservationService class assigned to the provided service definition, based on the work_script and work_class properties provided.
@param service_def [ServiceDefinition] definition of service to retrieve class for @return [Class] class of work_script
# File lib/longleaf/services/service_class_cache.rb, line 38 def service_class(service_def) service_name = service_def.name work_script = service_def.work_script if work_script.include?('/') expanded_path = Pathname.new(work_script).expand_path.to_s if !from_permitted_path?(expanded_path) raise ConfigurationError.new("Unable to load work_script for service #{service_name}, #{work_script} is not in a known library path.") end last_slash_index = work_script.rindex('/') script_path = work_script[0..last_slash_index] script_name = work_script[(last_slash_index + 1)..-1] else script_path = STD_PRESERVATION_SERVICE_PATH script_name = work_script end # Strip off the extension script_name.sub!('.rb', '') require_path = File.join(script_path, script_name) # Return the cached Class if this path has been encountered before if @class_cache.key?(require_path) return @class_cache[require_path] end # Load the script begin require require_path rescue LoadError raise ConfigurationError.new("Failed to load work_script '#{script_name}' for service #{service_name}") end # Generate the class name, either configured or from file naming convention if possible if service_def.work_class class_name = service_def.work_class else class_name = script_name.split('_').map(&:capitalize).join # Assume the longleaf module for classes in the standard path class_name = 'Longleaf::' + class_name if script_path == STD_PRESERVATION_SERVICE_PATH end begin class_constant = constantize(class_name) # cache the class for this work_script and return it @class_cache[require_path] = class_constant rescue NameError raise ConfigurationError.new("Failed to load work_script '#{script_name}' for service #{service_name}, class name #{class_name} was not found.") end end
service_instance(service_def)
click to toggle source
Returns an instance of the preversation service defined for the provided service definition, based on the work_script and work_class properties provided.
@param service_def [ServiceDefinition] definition of service to instantiate @return [PreservationService] Instance of the preservation service class for the definition.
# File lib/longleaf/services/service_class_cache.rb, line 21 def service_instance(service_def) service_name = service_def.name # Return the cached instance of the service if @service_instance_cache.key?(service_name) return @service_instance_cache[service_name] end clazz = service_class(service_def) # Cache and return the class instance @service_instance_cache[service_name] = clazz.new(service_def, @app_manager) end
Private Instance Methods
constantize(str)
click to toggle source
Borrowed from sidekiq implementation
# File lib/longleaf/services/service_class_cache.rb, line 92 def constantize(str) names = str.split('::') names.shift if names.empty? || names.first.empty? names.inject(Object) do |constant, name| # the false flag limits search for name to under the constant namespace # which mimics Rails' behaviour constant.const_defined?(name, false) ? constant.const_get(name, false) : constant.const_missing(name) end end
from_permitted_path?(script_path)
click to toggle source
# File lib/longleaf/services/service_class_cache.rb, line 103 def from_permitted_path?(script_path) $LOAD_PATH.each do |lib_path| if script_path.start_with?(lib_path) return true end end false end