Module: Custodian::Core::Adjuster

Defined in:
lib/custodian/core/adjuster.rb

Constant Summary collapse

VALID_STRICTNESS_VALUES =
%i[valid trustworthy].freeze

Class Method Summary collapse

Class Method Details

.aggregate_demand(root_node) ⇒ Object

Computes, for every node in root_node's subtree, its consolidated demand (own demand_value + aggregated demand_value of numeric descendants). Pure calculation: no persistence, no ActionRegistry calls, no mutation of any record.

Loads the whole subtree in a single query, then works entirely in memory (children are grouped by parent_id parsed from the ancestry column, never via DB-querying association methods) so the query count does not scale with tree size.



56
57
58
59
60
61
62
63
64
65
# File 'lib/custodian/core/adjuster.rb', line 56

def aggregate_demand(root_node)
  nodes = root_node.subtree.to_a
  children_by_parent_id = nodes.group_by { |node| parent_id_of(node) }

  results = {}
  post_order(root_node, children_by_parent_id) do |node|
    results[node.id] = compute(node, children_by_parent_id[node.id] || [], results)
  end
  results
end

.clear_phases!Object

Removes all registered phases. Intended for test isolation.



25
26
27
# File 'lib/custodian/core/adjuster.rb', line 25

def clear_phases!
  @phases_mutex.synchronize { @phases = [] }
end

.register_phase(name, handler) ⇒ Object

Registers a resolution phase, run (in registration order) between direct custodies and escalation for every node still unresolved. This is the extension point a future sibling-generosity satellite plugs into; this step only builds the hook, not any phase itself.



18
19
20
21
22
# File 'lib/custodian/core/adjuster.rb', line 18

def register_phase(name, handler)
  @phases_mutex.synchronize do
    @phases << { name: name, handler: handler }.freeze
  end
end

.resolve_tree(root_node, strictness: :valid) ⇒ Object

Walks root_node's subtree post-order (leaves first), invoking registered actions through each node's custodies, and escalating unresolved demand to the direct parent (see the class docs for the full encapsulation design). Pure resolution: never persists or mutates any Node/Custody record. Actions themselves may have side effects; that is their business, not the Adjuster's.



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/custodian/core/adjuster.rb', line 35

def resolve_tree(root_node, strictness: :valid)
  validate_strictness!(strictness)
  state = build_resolution_state(root_node, strictness)

  post_order(root_node, state[:children_by_parent_id]) do |node|
    resolve_and_escalate(node, state)
  end

  settle_numeric_escalations!(state[:results], state[:parent_id_by_node_id], root_node.id)
  state[:results]
end