Class: BreakerMachines::CascadingCircuit

Inherits:
CoordinatedCircuit show all
Defined in:
lib/breaker_machines/cascading_circuit.rb

Overview

CascadingCircuit extends the CoordinatedCircuit class with the ability to automatically trip dependent circuits when this circuit opens. This enables sophisticated failure cascade modeling, similar to how critical system failures in a starship would cascade to dependent subsystems.

Examples:

Starship network dependency

# Network circuit that cascades to dependent systems
network_circuit = BreakerMachines::CascadingCircuit.new('subspace_network', {
  failure_threshold: 1,
  cascades_to: ['weapons_targeting', 'navigation_sensors', 'communications'],
  emergency_protocol: :red_alert
})

# When network fails, all dependent systems are automatically tripped
network_circuit.call { raise 'Subspace relay offline!' }
# => All dependent circuits are now open

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from BreakerMachines::Circuit::CoordinatedStateManagement

#recovery_allowed?, #reset_allowed?

Constructor Details

#initialize(name, config = {}) ⇒ CascadingCircuit

Returns a new instance of CascadingCircuit.



26
27
28
29
30
31
# File 'lib/breaker_machines/cascading_circuit.rb', line 26

def initialize(name, config = {})
  @dependent_circuits = Array(config.delete(:cascades_to))
  @emergency_protocol = config.delete(:emergency_protocol)

  super
end

Instance Attribute Details

#dependent_circuitsObject (readonly)

Returns the value of attribute dependent_circuits.



24
25
26
# File 'lib/breaker_machines/cascading_circuit.rb', line 24

def dependent_circuits
  @dependent_circuits
end

#emergency_protocolObject (readonly)

Returns the value of attribute emergency_protocol.



24
25
26
# File 'lib/breaker_machines/cascading_circuit.rb', line 24

def emergency_protocol
  @emergency_protocol
end

Instance Method Details

#cascade_failure!Object

Force cascade failure to all dependent circuits



41
42
43
# File 'lib/breaker_machines/cascading_circuit.rb', line 41

def cascade_failure!
  perform_cascade
end

#cascade_infoObject

Provide cascade info for introspection



79
80
81
82
83
84
85
86
# File 'lib/breaker_machines/cascading_circuit.rb', line 79

def cascade_info
  BreakerMachines::CascadeInfo.new(
    dependent_circuits: @dependent_circuits,
    emergency_protocol: @emergency_protocol,
    cascade_triggered_at: @cascade_triggered_at&.value,
    dependent_status: dependent_status
  )
end

#dependent_statusObject

Get the current status of all dependent circuits



46
47
48
49
50
51
52
53
# File 'lib/breaker_machines/cascading_circuit.rb', line 46

def dependent_status
  return {} if @dependent_circuits.empty?

  @dependent_circuits.each_with_object({}) do |circuit_name, status|
    circuit = BreakerMachines.registry.find(circuit_name)
    status[circuit_name] = circuit ? circuit.status_name : :not_found
  end
end

#dependents_compromised?Boolean

Check if any dependent circuits are open

Returns:

  • (Boolean)


56
57
58
59
60
61
# File 'lib/breaker_machines/cascading_circuit.rb', line 56

def dependents_compromised?
  @dependent_circuits.any? do |circuit_name|
    circuit = BreakerMachines.registry.find(circuit_name)
    circuit&.open?
  end
end

#summaryObject

Summary that includes cascade information



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/breaker_machines/cascading_circuit.rb', line 64

def summary
  base_summary = super
  return base_summary if @dependent_circuits.empty?

  if @cascade_triggered_at&.value
    compromised_count = dependent_status.values.count(:open)
    " CASCADE TRIGGERED: #{compromised_count}/#{@dependent_circuits.length} dependent systems compromised."
  else
    " Monitoring #{@dependent_circuits.length} dependent systems."
  end

  base_summary + cascade_info_text
end

#trip!Object

Override the trip method to include cascading behavior



34
35
36
37
38
# File 'lib/breaker_machines/cascading_circuit.rb', line 34

def trip!
  result = super
  perform_cascade if result && @dependent_circuits.any?
  result
end