Class: Aidp::AutoUpdate::FailureTracker
- Inherits:
-
Object
- Object
- Aidp::AutoUpdate::FailureTracker
- Includes:
- SafeDirectory
- Defined in:
- lib/aidp/auto_update/failure_tracker.rb
Overview
Service for tracking update failures to prevent restart loops
Instance Attribute Summary collapse
-
#max_failures ⇒ Object
readonly
Returns the value of attribute max_failures.
-
#state_file ⇒ Object
readonly
Returns the value of attribute state_file.
Instance Method Summary collapse
-
#failure_count ⇒ Integer
Get current failure count.
-
#failure_timestamps ⇒ Array<Time>
Get all failure timestamps.
-
#force_reset ⇒ Object
Manually reset failures (for CLI command or recovery).
-
#initialize(project_dir: Dir.pwd, max_failures: 3) ⇒ FailureTracker
constructor
A new instance of FailureTracker.
-
#record_failure ⇒ Object
Record a failure.
-
#reset_on_success ⇒ Object
Reset failure count after successful operation.
-
#status ⇒ Hash
Get state summary for status display.
-
#time_since_last_success ⇒ Integer?
Get time since last success.
-
#too_many_failures? ⇒ Boolean
Check if too many consecutive failures have occurred.
Methods included from SafeDirectory
Constructor Details
#initialize(project_dir: Dir.pwd, max_failures: 3) ⇒ FailureTracker
Returns a new instance of FailureTracker.
16 17 18 19 20 21 22 23 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 16 def initialize(project_dir: Dir.pwd, max_failures: 3) @project_dir = project_dir state_dir = File.join(project_dir, ".aidp") actual_dir = safe_mkdir_p(state_dir, component_name: "FailureTracker") @state_file = File.join(actual_dir, "auto_update_failures.json") @max_failures = max_failures @state = load_state end |
Instance Attribute Details
#max_failures ⇒ Object (readonly)
Returns the value of attribute max_failures.
14 15 16 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 14 def max_failures @max_failures end |
#state_file ⇒ Object (readonly)
Returns the value of attribute state_file.
14 15 16 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 14 def state_file @state_file end |
Instance Method Details
#failure_count ⇒ Integer
Get current failure count
82 83 84 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 82 def failure_count @state[:failures].size end |
#failure_timestamps ⇒ Array<Time>
Get all failure timestamps
100 101 102 103 104 105 106 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 100 def @state[:failures].map { |f| Time.parse(f[:timestamp]) } rescue => e Aidp.log_error("failure_tracker", "timestamp_parsing_failed", error: e.) [] end |
#force_reset ⇒ Object
Manually reset failures (for CLI command or recovery)
109 110 111 112 113 114 115 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 109 def force_reset Aidp.log_warn("failure_tracker", "manual_reset_triggered", previous_failures: @state[:failures].size) @state[:failures] = [] save_state end |
#record_failure ⇒ Object
Record a failure
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 26 def record_failure @state[:failures] << { timestamp: Time.now.utc.iso8601, version: Aidp::VERSION } # Keep only recent failures (last hour) @state[:failures].select! { |f| Time.parse(f[:timestamp]) > Time.now - 3600 } save_state Aidp.log_warn("failure_tracker", "failure_recorded", total_failures: @state[:failures].size, max_failures: @max_failures) rescue => e Aidp.log_error("failure_tracker", "record_failure_failed", error: e.) end |
#reset_on_success ⇒ Object
Reset failure count after successful operation
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 63 def reset_on_success previous_failures = @state[:failures].size @state[:failures] = [] @state[:last_success] = Time.now.utc.iso8601 @state[:last_success_version] = Aidp::VERSION save_state Aidp.log_info("failure_tracker", "reset_on_success", previous_failures: previous_failures, version: Aidp::VERSION) rescue => e Aidp.log_error("failure_tracker", "reset_failed", error: e.) end |
#status ⇒ Hash
Get state summary for status display
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 119 def status { failure_count: failure_count, max_failures: @max_failures, too_many_failures: too_many_failures?, last_success: @state[:last_success], last_success_version: @state[:last_success_version], recent_failures: @state[:failures] } end |
#time_since_last_success ⇒ Integer?
Get time since last success
88 89 90 91 92 93 94 95 96 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 88 def time_since_last_success return nil unless @state[:last_success] Time.now - Time.parse(@state[:last_success]) rescue => e Aidp.log_error("failure_tracker", "time_calculation_failed", error: e.) nil end |
#too_many_failures? ⇒ Boolean
Check if too many consecutive failures have occurred
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/aidp/auto_update/failure_tracker.rb', line 49 def too_many_failures? failure_count = @state[:failures].size is_looping = failure_count >= @max_failures if is_looping Aidp.log_error("failure_tracker", "restart_loop_detected", failure_count: failure_count, max_failures: @max_failures) end is_looping end |