Module: Smith::Agent::Registry
- Extended by:
- Dry::Container::Mixin
- Defined in:
- lib/smith/agent/registry.rb
Class Method Summary collapse
- .clear! ⇒ Object
- .delete(name) ⇒ Object
- .ensure_registered(name, klass) ⇒ Object
- .fetch!(name, workflow_class: nil, transition_name: nil, role: :agent) ⇒ Object
- .find(name) ⇒ Object
- .normalize_key(name) ⇒ Object
-
.register(key, contents = nil, options = {}, &block) ⇒ Object
Override Dry::Container::Mixin#register to route agent classes through ensure_registered while preserving full generic container semantics (block, options) for non-agent registrations.
-
.registry_monitor ⇒ Object
Re-entrant lock (Monitor, not Mutex) so block-backed resolve inside find/fetch! can safely re-enter the registry without deadlocking on the same thread.
- .validate_agent_class!(klass) ⇒ Object
Class Method Details
.clear! ⇒ Object
39 40 41 42 43 |
# File 'lib/smith/agent/registry.rb', line 39 def self.clear! registry_monitor.synchronize do @_container&.clear end end |
.delete(name) ⇒ Object
33 34 35 36 37 |
# File 'lib/smith/agent/registry.rb', line 33 def self.delete(name) registry_monitor.synchronize do _container.delete(normalize_key(name)) end end |
.ensure_registered(name, klass) ⇒ Object
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 |
# File 'lib/smith/agent/registry.rb', line 45 def self.ensure_registered(name, klass) validate_agent_class!(klass) key = normalize_key(name) registry_monitor.synchronize do existing = key?(key) ? resolve(key) : nil if existing.nil? register_unchecked!(key, klass) elsif existing.equal?(klass) # same object — no-op elsif stale_reload_binding?(existing, klass) # same class name, different object — Rails reload case _container.delete(key) register_unchecked!(key, klass) else raise Smith::AgentRegistryError, "agent registry collision for key #{key.inspect}: " \ "already registered to #{binding_label(existing)}, " \ "cannot replace with #{binding_label(klass)}" end klass end end |
.fetch!(name, workflow_class: nil, transition_name: nil, role: :agent) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/smith/agent/registry.rb', line 71 def self.fetch!(name, workflow_class: nil, transition_name: nil, role: :agent) registry_monitor.synchronize do key = normalize_key(name) return resolve(key) if key?(key) details = [] details << "workflow #{workflow_class}" if workflow_class details << "transition :#{transition_name}" if transition_name suffix = details.empty? ? "" : " for #{details.join(', ')}" raise Smith::WorkflowError, "unresolved #{role} :#{key}#{suffix}" end end |
.find(name) ⇒ Object
15 16 17 18 19 20 |
# File 'lib/smith/agent/registry.rb', line 15 def self.find(name) registry_monitor.synchronize do key = normalize_key(name) key?(key) ? resolve(key) : nil end end |
.normalize_key(name) ⇒ Object
11 12 13 |
# File 'lib/smith/agent/registry.rb', line 11 def self.normalize_key(name) name.to_s end |
.register(key, contents = nil, options = {}, &block) ⇒ Object
Override Dry::Container::Mixin#register to route agent classes through ensure_registered while preserving full generic container semantics (block, options) for non-agent registrations.
25 26 27 28 29 30 31 |
# File 'lib/smith/agent/registry.rb', line 25 def self.register(key, contents = nil, = {}, &block) if block_given? || !(contents.is_a?(Class) && contents <= Smith::Agent) registry_monitor.synchronize { super(key, contents, , &block) } else ensure_registered(key, contents) end end |
.registry_monitor ⇒ Object
Re-entrant lock (Monitor, not Mutex) so block-backed resolve inside find/fetch! can safely re-enter the registry without deadlocking on the same thread.
88 89 90 |
# File 'lib/smith/agent/registry.rb', line 88 def self.registry_monitor @_registry_monitor ||= Monitor.new end |
.validate_agent_class!(klass) ⇒ Object
92 93 94 95 96 97 |
# File 'lib/smith/agent/registry.rb', line 92 def self.validate_agent_class!(klass) return if klass.is_a?(Class) && klass <= Smith::Agent raise Smith::AgentRegistryError, "expected a Smith::Agent subclass, got #{klass.inspect}" end |