Module: Smith::Agent::Registry

Extended by:
Dry::Container::Mixin, ExecutionBindingCapture, Introspection, MutationBoundary
Defined in:
lib/smith/agent/registry.rb,
lib/smith/agent/registry/introspection.rb,
lib/smith/agent/registry/mutation_boundary.rb,
lib/smith/agent/registry/execution_binding_capture.rb

Defined Under Namespace

Modules: ExecutionBindingCapture, Introspection, MutationBoundary

Class Method Summary collapse

Methods included from ExecutionBindingCapture

capture_bindings!

Methods included from MutationBoundary

configure, decorate, import, merge, namespace

Methods included from Introspection

binding_for, bindings

Class Method Details

.clear!Object



40
41
42
43
44
# File 'lib/smith/agent/registry.rb', line 40

def self.clear!
  registry_monitor.synchronize do
    @_container&.clear
  end
end

.delete(name) ⇒ Object



34
35
36
37
38
# File 'lib/smith/agent/registry.rb', line 34

def self.delete(name)
  registry_monitor.synchronize do
    _container.delete(normalize_key(name))
  end
end

.ensure_registered(name, klass) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/smith/agent/registry.rb', line 46

def self.ensure_registered(name, klass)
  validate_agent_class!(klass)
  key = normalize_key(name)

  registry_monitor.synchronize do
    existing = registered_binding(key)

    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



72
73
74
75
76
77
78
79
80
# File 'lib/smith/agent/registry.rb', line 72

def self.fetch!(name, workflow_class: nil, transition_name: nil, role: :agent)
  registry_monitor.synchronize do
    key = normalize_key(name)
    binding = registered_binding(key)
    return binding if binding

    raise Smith::WorkflowError, "unresolved #{role} :#{key}#{fetch_suffix(workflow_class, transition_name)}"
  end
end

.find(name) ⇒ Object



20
21
22
23
24
# File 'lib/smith/agent/registry.rb', line 20

def self.find(name)
  registry_monitor.synchronize do
    registered_binding(normalize_key(name))
  end
end

.normalize_key(name) ⇒ Object



16
17
18
# File 'lib/smith/agent/registry.rb', line 16

def self.normalize_key(name)
  name.to_s
end

.register(key, contents = nil, options = {}, &block) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/smith/agent/registry.rb', line 26

def self.register(key, contents = nil, options = {}, &block)
  if block_given? || !(contents.is_a?(Class) && contents <= Smith::Agent)
    registry_monitor.synchronize { super(key, contents, options, &block) }
  else
    ensure_registered(key, contents)
  end
end

.registry_monitorObject



82
83
84
# File 'lib/smith/agent/registry.rb', line 82

def self.registry_monitor
  @registry_monitor ||= Monitor.new
end

.validate_agent_class!(klass) ⇒ Object



86
87
88
89
90
91
# File 'lib/smith/agent/registry.rb', line 86

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