class Dry::System::Booter
Default booter implementation
This is currently configured by default for every System::Container
. Booter
objects are responsible for loading system/boot files and expose an API for calling lifecycle triggers.
@api private
Attributes
Public Class Methods
@api private
# File lib/dry/system/booter.rb, line 27 def initialize(paths) @paths = paths @booted = [] @components = ComponentRegistry.new end
Public Instance Methods
@api private
# File lib/dry/system/booter.rb, line 135 def boot_dependency(component) if (component = find_component(component.root_key)) start(component) end end
Returns all boot files within the configured paths
Searches for files in the order of the configured paths. In the case of multiple identically-named boot files within different paths, the file found first will be returned, and other matching files will be discarded.
@return [Array<Pathname>] @api public
# File lib/dry/system/booter.rb, line 149 def boot_files @boot_files ||= paths.each_with_object([[], []]) { |path, (boot_files, loaded)| files = Dir["#{path}/#{RB_GLOB}"].sort files.each do |file| basename = File.basename(file) unless loaded.include?(basename) boot_files << Pathname(file) loaded << basename end end }.first end
@api private
# File lib/dry/system/booter.rb, line 124 def call(name_or_component) with_component(name_or_component) do |component| raise ComponentFileMismatchError, name unless component yield(component) if block_given? component end end
@api private
# File lib/dry/system/booter.rb, line 56 def finalize! boot_files.each do |path| load_component(path) end components.each do |component| start(component) end freeze end
Returns a bootable component if it can be found or loaded, otherwise nil
@return [Dry::System::Components::Bootable, nil] @api private
# File lib/dry/system/booter.rb, line 43 def find_component(name) name = name.to_sym return components[name] if components.exists?(name) return if finalized? require_boot_file(name) components[name] if components.exists?(name) end
@api private
# File lib/dry/system/booter.rb, line 85 def init(name_or_component) with_component(name_or_component) do |component| call(component) do component.init.finalize yield if block_given? end self end end
@api private
# File lib/dry/system/booter.rb, line 34 def register_component(component) components.register(component) self end
@api private
# File lib/dry/system/booter.rb, line 76 def shutdown components.each do |component| next unless booted.include?(component) stop(component) end end
@api private
# File lib/dry/system/booter.rb, line 97 def start(name_or_component) with_component(name_or_component) do |component| return self if booted.include?(component) init(name_or_component) do component.start end booted << component.finalize self end end
@api private
# File lib/dry/system/booter.rb, line 112 def stop(name_or_component) call(name_or_component) do |component| raise ComponentNotStartedError, name_or_component unless booted.include?(component) component.stop booted.delete(component) yield if block_given? end end
Private Instance Methods
# File lib/dry/system/booter.rb, line 195 def find_boot_file(name) boot_files.detect { |file| File.basename(file, RB_EXT) == name.to_s } end
# File lib/dry/system/booter.rb, line 181 def load_component(path) identifier = Pathname(path).basename(RB_EXT).to_s.to_sym Kernel.require path unless components.exists?(identifier) self end
# File lib/dry/system/booter.rb, line 189 def require_boot_file(identifier) boot_file = find_boot_file(identifier) Kernel.require boot_file if boot_file end
# File lib/dry/system/booter.rb, line 166 def with_component(id_or_component) component = case id_or_component when Symbol require_boot_file(id_or_component) unless components.exists?(id_or_component) components[id_or_component] when Components::Bootable id_or_component end raise InvalidComponentError, id_or_component unless component yield(component) end