Module: BreakerMachines::Circuit::Introspection

Extended by:
ActiveSupport::Concern
Defined in:
lib/breaker_machines/circuit/introspection.rb

Overview

Introspection provides methods for inspecting circuit state, statistics, and generating human-readable summaries of circuit status.

Instance Method Summary collapse

Instance Method Details

#configurationObject



27
28
29
# File 'lib/breaker_machines/circuit/introspection.rb', line 27

def configuration
  @config.dup
end

#event_log(limit: 20) ⇒ Object



31
32
33
# File 'lib/breaker_machines/circuit/introspection.rb', line 31

def event_log(limit: 20)
  @storage.event_log(@name, limit) if @storage.respond_to?(:event_log)
end

#last_errorObject



35
36
37
# File 'lib/breaker_machines/circuit/introspection.rb', line 35

def last_error
  @last_error.value
end

#last_error_infoObject



81
82
83
84
85
86
87
88
89
90
# File 'lib/breaker_machines/circuit/introspection.rb', line 81

def last_error_info
  error = @last_error.value
  return nil unless error

  BreakerMachines::ErrorInfo.new(
    error_class: error.class.name,
    message: error.message,
    occurred_at: @last_failure_at.value
  )
end

#statsObject

State check methods are automatically generated by state_machines:

  • open? (returns true when status == :open)

  • closed? (returns true when status == :closed)

  • half_open? (returns true when status == :half_open)



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/breaker_machines/circuit/introspection.rb', line 15

def stats
  BreakerMachines::Stats.new(
    state: status_name,
    failure_count: @storage.failure_count(@name, @config[:failure_window]),
    success_count: @storage.success_count(@name, @config[:failure_window]),
    last_failure_at: @last_failure_at.value,
    opened_at: @opened_at.value,
    half_open_attempts: @half_open_attempts.value,
    half_open_successes: @half_open_successes.value
  )
end

#summaryObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/breaker_machines/circuit/introspection.rb', line 55

def summary
  base_summary = case status_name
                 when :closed
                   "Circuit '#{@name}' is CLOSED. #{stats.failure_count} failures recorded."
                 when :open
                   # Calculate time remaining until reset
                   time_since_open = BreakerMachines.monotonic_time - @opened_at.value
                   time_until_reset = @config[:reset_timeout] - time_since_open
                   reset_time = time_until_reset.seconds.from_now
                   opened_time = time_since_open.seconds.ago
                   error_info = @last_error.value ? " The last error was #{@last_error.value.class}." : ''
                   "Circuit '#{@name}' is OPEN until #{reset_time}. " \
                     "It opened at #{opened_time} after #{@config[:failure_threshold]} failures.#{error_info}"
                 when :half_open
                   "Circuit '#{@name}' is HALF-OPEN. Testing with limited requests " \
                   "(#{@half_open_attempts.value}/#{@config[:half_open_calls]} attempts)."
                 end

  # Add cascade information if this is a cascading circuit
  if is_a?(CascadingCircuit) && @dependent_circuits.any?
    base_summary += " [Cascades to: #{@dependent_circuits.join(', ')}]"
  end

  base_summary
end

#to_hObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/breaker_machines/circuit/introspection.rb', line 39

def to_h
  hash = {
    name: @name,
    state: status_name,
    stats: stats.to_h,
    config: configuration.except(:owner, :storage, :metrics),
    event_log: event_log || [],
    last_error: last_error_info&.to_h
  }

  # Add cascade-specific information if this is a cascading circuit
  hash[:cascade_info] = cascade_info.to_h if is_a?(CascadingCircuit)

  hash
end