Class: Hames::Loader

Inherits:
Object
  • Object
show all
Defined in:
lib/hames/loader.rb

Overview

Mounts config rows into a context in dependency order derived from each plugin's inject list. Layers apply as ordered row lists; a later layer's row with an existing id replaces that row's config wholesale (never a deep merge); unknown ids append.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ctx = Context.new) ⇒ Loader

Returns a new instance of Loader.



51
52
53
54
55
# File 'lib/hames/loader.rb', line 51

def initialize(ctx = Context.new)
  @ctx = ctx
  @rows = {} # id => Row
  @mounted = {} # id => plugin instance
end

Instance Attribute Details

#ctxObject (readonly)

Returns the value of attribute ctx.



49
50
51
# File 'lib/hames/loader.rb', line 49

def ctx
  @ctx
end

#rowsObject (readonly)

Returns the value of attribute rows.



49
50
51
# File 'lib/hames/loader.rb', line 49

def rows
  @rows
end

Instance Method Details

#boot!Object

Mount all enabled rows. Plugins whose injected services are not yet present wait; repeated passes mount whatever has become satisfiable. No progress with plugins still pending => cycle / missing provider.



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/hames/loader.rb', line 78

def boot!
  pending = @rows.values.reject(&:disabled).map { |r| [r, instantiate(r)] }
  until pending.empty?
    ready, pending = pending.partition { |(_r, pl)| satisfied?(pl) }
    if ready.empty?
      missing = pending.map { |(r, pl)| "#{r.id} (needs #{unmet(pl).join(', ')})" }
      raise CycleError, "cannot mount: #{missing.join('; ')}"
    end
    ready.each { |(r, pl)| mount(r, pl) }
  end
  ctx
end

#dump_configObject

Resolved tree, layer-agnostic view (for --dump-config).



98
99
100
# File 'lib/hames/loader.rb', line 98

def dump_config
  @rows.values.map { |r| { id: r.id, plugin: r.plugin.to_s, config: r.config, disabled: r.disabled } }
end

#layer(row_hashes) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/hames/loader.rb', line 57

def layer(row_hashes)
  row_hashes.each do |h|
    id = h.fetch(:id).to_s
    if (existing = @rows[id])
      # patch: wholesale config replacement; plugin class may also swap
      @rows[id] = Hames::Row.new(
        id: id,
        plugin: h[:plugin] || existing.plugin,
        config: h.key?(:config) ? (h[:config] || {}) : existing.config,
        disabled: h.key?(:disabled) ? h[:disabled] : existing.disabled
      )
    else
      @rows[id] = Row.build(h)
    end
  end
  self
end

#unload!(id) ⇒ Object



91
92
93
94
95
# File 'lib/hames/loader.rb', line 91

def unload!(id)
  plugin = @mounted.delete(id) or raise ArgumentError, "no mounted plugin #{id}"
  plugin.stop(ctx) if plugin.respond_to?(:stop)
  ctx.dispose_owner!(id)
end