Class: Dry::System::Components::Bootable

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/system/components/bootable.rb

Overview

Bootable components can provide one or more objects and typically depend on 3rd-party code. A typical bootable component can be a database library, or an API client.

These components can be registered via ‘Container.boot` and external component providers can register their components too, which then can be used and configured by your system.

Examples:

simple logger

class App < Dry::System::Container
  boot(:logger) do
    init do
      require "logger"
    end

    start do
      register(:logger, Logger.new($stdout))
    end
  end
end

App[:logger] # returns configured logger

using built-in system components

class App < Dry::System::Container
  boot(:settings, from: :system) do
    settings do
      key :database_url, Types::String.constrained(filled: true)
      key :session_secret, Types::String.constrained(filled: true)
    end
  end
end

App[:settings] # returns loaded settings

Constant Summary collapse

DEFAULT_FINALIZE =
proc {}
TRIGGER_MAP =
Hash.new { |h, k| h[k] = [] }.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(identifier, options = {}, &block) ⇒ Bootable

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Bootable.



73
74
75
76
77
78
79
80
# File 'lib/dry/system/components/bootable.rb', line 73

def initialize(identifier, options = {}, &block)
  @identifier = identifier
  @triggers = { before: TRIGGER_MAP.dup, after: TRIGGER_MAP.dup }
  @options = block ? options.merge(block: block) : options
  @namespace = options[:namespace]
  finalize = options[:finalize] || DEFAULT_FINALIZE
  instance_exec(&finalize)
end

Instance Attribute Details

#finalizeBootable (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Automatically called by the booter object after starting a component



56
57
58
# File 'lib/dry/system/components/bootable.rb', line 56

def finalize
  @finalize
end

#identifierObject (readonly)



52
53
54
# File 'lib/dry/system/components/bootable.rb', line 52

def identifier
  @identifier
end

#namespaceObject (readonly)



68
69
70
# File 'lib/dry/system/components/bootable.rb', line 68

def namespace
  @namespace
end

#optionsObject (readonly)



60
61
62
# File 'lib/dry/system/components/bootable.rb', line 60

def options
  @options
end

#triggersObject (readonly)



64
65
66
# File 'lib/dry/system/components/bootable.rb', line 64

def triggers
  @triggers
end

Instance Method Details

#after(event, &block) ⇒ Bootable

Specify an after callback



131
132
133
134
# File 'lib/dry/system/components/bootable.rb', line 131

def after(event, &block)
  triggers[:after][event] << block
  self
end

#before(event, &block) ⇒ Bootable

Specify a before callback



121
122
123
124
# File 'lib/dry/system/components/bootable.rb', line 121

def before(event, &block)
  triggers[:before][event] << block
  self
end

#boot?TrueClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return true



234
235
236
# File 'lib/dry/system/components/bootable.rb', line 234

def boot?
  true
end

#boot_fileString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return path to component’s boot file



243
244
245
246
# File 'lib/dry/system/components/bootable.rb', line 243

def boot_file
  container_boot_files
    .detect { |path| Pathname(path).basename(RB_EXT).to_s == identifier.to_s }
end

#boot_pathString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return path to boot dir



253
254
255
# File 'lib/dry/system/components/bootable.rb', line 253

def boot_path
  container.boot_path
end

#configDry::Struct

Return component’s configuration



165
166
167
# File 'lib/dry/system/components/bootable.rb', line 165

def config
  @config || configure!
end

#configure(&block) ⇒ Bootable

Configure a component



141
142
143
# File 'lib/dry/system/components/bootable.rb', line 141

def configure(&block)
  @config_block = block
end

#containerDry::Struct

Return system’s container used by this component



183
184
185
# File 'lib/dry/system/components/bootable.rb', line 183

def container
  options.fetch(:container)
end

#container_boot_filesString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return all boot files defined under container’s boot path



262
263
264
# File 'lib/dry/system/components/bootable.rb', line 262

def container_boot_files
  ::Dir[container.boot_path.join("**/#{RB_GLOB}")].sort
end

#initBootable

Execute ‘init` step



87
88
89
90
91
92
# File 'lib/dry/system/components/bootable.rb', line 87

def init
  trigger(:before, :init)
  lifecycle.(:init)
  trigger(:after, :init)
  self
end

#new(identifier, new_options = EMPTY_HASH) ⇒ Dry::Struct

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a new instance with updated name and options



216
217
218
# File 'lib/dry/system/components/bootable.rb', line 216

def new(identifier, new_options = EMPTY_HASH)
  self.class.new(identifier, options.merge(new_options))
end

#settings(&block) ⇒ Bootable

Define configuration settings with keys and types



150
151
152
153
154
155
156
157
158
# File 'lib/dry/system/components/bootable.rb', line 150

def settings(&block)
  if block
    @settings_block = block
  elsif @settings_block
    @settings = Settings::DSL.new(identifier, &@settings_block).call
  else
    @settings
  end
end

#startBootable

Execute ‘start` step



99
100
101
102
103
104
# File 'lib/dry/system/components/bootable.rb', line 99

def start
  trigger(:before, :start)
  lifecycle.(:start)
  trigger(:after, :start)
  self
end

#statusesArray<Symbol>

Return a list of lifecycle steps that were executed



174
175
176
# File 'lib/dry/system/components/bootable.rb', line 174

def statuses
  lifecycle.statuses
end

#stopBootable

Execute ‘stop` step



111
112
113
114
# File 'lib/dry/system/components/bootable.rb', line 111

def stop
  lifecycle.(:stop)
  self
end

#trigger(key, event) ⇒ Bootable

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Trigger a callback



204
205
206
207
208
209
# File 'lib/dry/system/components/bootable.rb', line 204

def trigger(key, event)
  triggers[key][event].each do |fn|
    container.instance_exec(lifecycle.container, &fn)
  end
  self
end

#with(new_options) ⇒ Dry::Struct

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a new instance with updated options



225
226
227
# File 'lib/dry/system/components/bootable.rb', line 225

def with(new_options)
  self.class.new(identifier, options.merge(new_options))
end