Module: HybridStateModel::Metrics

Defined in:
lib/hybrid_state_model/metrics.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



7
8
9
# File 'lib/hybrid_state_model/metrics.rb', line 7

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#current_state_durationObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/hybrid_state_model/metrics.rb', line 104

def current_state_duration
  return 0 unless persisted?

  current_primary = primary_state_value
  return 0 unless current_primary

  metrics = state_metrics_hash[current_primary.to_s] || {}
  entered_at = metrics["entered_at"]

  return 0 unless entered_at

  base_duration = metrics["duration"] || 0
  time_since_entry = Time.now - Time.parse(entered_at)
  base_duration + time_since_entry
end

#record_state_metricsObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hybrid_state_model/metrics.rb', line 25

def record_state_metrics
  return unless @state_changed

  metrics = state_metrics_hash
  current_time = Time.now

  # Record exit time for old state
  if @old_primary
    metrics[@old_primary.to_s] ||= {}
    metrics[@old_primary.to_s]["exited_at"] ||= current_time.iso8601
    metrics[@old_primary.to_s]["duration"] ||= 0
    if metrics[@old_primary.to_s]["entered_at"]
      duration = current_time - Time.parse(metrics[@old_primary.to_s]["entered_at"])
      metrics[@old_primary.to_s]["duration"] += duration
    end
  end

  # Record entry time for new state
  new_primary = primary_state_value
  if new_primary
    metrics[new_primary.to_s] ||= {}
    metrics[new_primary.to_s]["entered_at"] = current_time.iso8601
    metrics[new_primary.to_s]["duration"] ||= 0
  end

  # Record micro state metrics
  if @old_micro && @old_primary
    micro_key = "#{@old_primary}:#{@old_micro}"
    metrics[micro_key] ||= {}
    metrics[micro_key]["exited_at"] ||= current_time.iso8601
    if metrics[micro_key]["entered_at"]
      duration = current_time - Time.parse(metrics[micro_key]["entered_at"])
      metrics[micro_key]["duration"] ||= 0
      metrics[micro_key]["duration"] += duration
    end
  end

  if micro_state_value && new_primary
    micro_key = "#{new_primary}:#{micro_state_value}"
    metrics[micro_key] ||= {}
    metrics[micro_key]["entered_at"] = current_time.iso8601
    metrics[micro_key]["duration"] ||= 0
  end

  # Store metrics if column exists
  if self.class.has_state_metrics?
    self.state_metrics = metrics.to_json
  end

  @state_changed = false
end

#state_metricsObject



77
78
79
80
81
82
83
84
85
86
# File 'lib/hybrid_state_model/metrics.rb', line 77

def state_metrics
  return {} unless self.class.has_state_metrics?

  json = read_attribute(:state_metrics)
  return {} if json.blank?

  JSON.parse(json)
rescue JSON::ParserError
  {}
end

#state_metrics_hashObject



88
89
90
# File 'lib/hybrid_state_model/metrics.rb', line 88

def state_metrics_hash
  state_metrics
end

#time_in_micro_state(primary_state, micro_state) ⇒ Object



98
99
100
101
102
# File 'lib/hybrid_state_model/metrics.rb', line 98

def time_in_micro_state(primary_state, micro_state)
  key = "#{primary_state}:#{micro_state}"
  metrics = state_metrics_hash[key] || {}
  metrics["duration"] || 0
end

#time_in_primary_state(state = nil) ⇒ Object



92
93
94
95
96
# File 'lib/hybrid_state_model/metrics.rb', line 92

def time_in_primary_state(state = nil)
  state ||= primary_state_value
  metrics = state_metrics_hash[state.to_s] || {}
  metrics["duration"] || 0
end

#track_state_changesObject



17
18
19
20
21
22
23
# File 'lib/hybrid_state_model/metrics.rb', line 17

def track_state_changes
  return unless persisted?

  @state_changed = primary_state_changed? || micro_state_changed?
  @old_primary = primary_state_was if primary_state_changed?
  @old_micro = micro_state_was if micro_state_changed?
end