Class: Longleaf::ServiceClassCache

Inherits:
Object
  • Object
show all
Defined in:
lib/longleaf/services/service_class_cache.rb

Overview

Cache for loading and retrieving preservation service classes

Constant Summary collapse

STD_PRESERVATION_SERVICE_PATH =
'longleaf/preservation_services/'

Instance Method Summary collapse

Constructor Details

#initialize(app_manager) ⇒ ServiceClassCache



8
9
10
11
12
13
14
# 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

Instance Method Details

#service_class(service_def) ⇒ Class

Load and return the PreservationService class assigned to the provided service definition, based on the work_script and work_class properties provided.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# 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) ⇒ PreservationService

Returns an instance of the preversation service defined for the provided service definition, based on the work_script and work_class properties provided.



21
22
23
24
25
26
27
28
29
30
31
# 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