Class: AIA::PluginLoader
- Inherits:
-
Object
- Object
- AIA::PluginLoader
- Defined in:
- lib/aia/plugin_loader.rb
Overview
Loads, reloads, and unloads top-level Ruby plugin files from the configured
plugins directory. A plugin is any *.rb file directly under
config.paths.plugins_dir; it may define top-level (Kernel) methods and/or
top-level constants. The loader tracks exactly what each file defines so a
changed plugin can be cleanly reloaded and a deleted plugin fully removed
from the running process.
Class Method Summary collapse
-
.load!(config) ⇒ Array<String>
Load every
*.rbfile at the top level of the plugins directory, starting from a clean slate (any previously-tracked definitions are removed first). -
.load_file(path, config = @config) ⇒ String?
Load — or, if already loaded, reload — a single plugin file.
-
.loaded_names ⇒ Array<String>
Sorted basenames currently loaded.
- .mutex ⇒ Object
-
.registry ⇒ Object
Per-process registry of loaded plugins, keyed by basename.
-
.reset!(config = @config) ⇒ void
Remove all tracked plugin definitions and clear the registry.
-
.unload_file(name, config = @config) ⇒ String?
Unload a plugin by basename: remove the methods and constants it defined and forget it.
Class Method Details
.load!(config) ⇒ Array<String>
Load every *.rb file at the top level of the plugins directory,
starting from a clean slate (any previously-tracked definitions are
removed first). Returns the sorted basenames of the loaded plugins.
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/aia/plugin_loader.rb', line 28 def load!(config) @config = config reset!(config) dir = plugins_dir(config) return [] unless dir Dir.glob(File.join(dir, '*.rb')).each { |file| load_file(file, config) } loaded_names end |
.load_file(path, config = @config) ⇒ String?
Load — or, if already loaded, reload — a single plugin file. On reload, the file's previous definitions are removed before re-executing so that renamed/deleted methods don't linger. Returns the basename, or nil on failure.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/aia/plugin_loader.rb', line 47 def load_file(path, config = @config) mutex.synchronize do name = File.basename(path, '.rb') remove_definitions(registry[name]) if registry.key?(name) before = current_definitions load(path) defined = diff_definitions(before, current_definitions) registry[name] = { path: path, signature: signature(path), defined: defined } sync_config(config) name end rescue ScriptError, StandardError => e warn_failure(path, e) nil end |
.loaded_names ⇒ Array<String>
Returns sorted basenames currently loaded.
81 82 83 |
# File 'lib/aia/plugin_loader.rb', line 81 def loaded_names registry.keys.sort end |
.mutex ⇒ Object
18 19 20 |
# File 'lib/aia/plugin_loader.rb', line 18 def mutex @mutex ||= Mutex.new end |
.registry ⇒ Object
Per-process registry of loaded plugins, keyed by basename. Each value: { path:, signature:, defined: { methods: [Symbol], constants: [Symbol] } }
14 15 16 |
# File 'lib/aia/plugin_loader.rb', line 14 def registry @registry ||= {} end |
.reset!(config = @config) ⇒ void
This method returns an undefined value.
Remove all tracked plugin definitions and clear the registry. Used by load! for a clean reload and by tests for isolation.
90 91 92 93 94 95 96 |
# File 'lib/aia/plugin_loader.rb', line 90 def reset!(config = @config) mutex.synchronize do registry.each_value { |entry| remove_definitions(entry) } registry.clear sync_config(config) end end |
.unload_file(name, config = @config) ⇒ String?
Unload a plugin by basename: remove the methods and constants it defined and forget it. Returns the basename if it was loaded, else nil.
71 72 73 74 75 76 77 78 |
# File 'lib/aia/plugin_loader.rb', line 71 def unload_file(name, config = @config) mutex.synchronize do entry = registry.delete(name) remove_definitions(entry) sync_config(config) entry && name end end |