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
-
.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).
-
.clear_phases! ⇒ Object
Removes all registered phases.
-
.register_phase(name, handler) ⇒ Object
Registers a resolution phase, run (in registration order) between direct custodies and escalation for every node still unresolved.
-
.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).
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 |