Class: Legion::Extensions::React::Helpers::LoopBreaker

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/extensions/react/helpers/loop_breaker.rb

Instance Method Summary collapse

Constructor Details

#initialize(max_depth: Constants::DEFAULT_MAX_DEPTH, cooldown_seconds: Constants::DEFAULT_COOLDOWN_SECONDS, max_per_hour: Constants::DEFAULT_MAX_REACTIONS_PER_HOUR) ⇒ LoopBreaker



8
9
10
11
12
13
14
15
16
# File 'lib/legion/extensions/react/helpers/loop_breaker.rb', line 8

def initialize(max_depth: Constants::DEFAULT_MAX_DEPTH,
               cooldown_seconds: Constants::DEFAULT_COOLDOWN_SECONDS,
               max_per_hour: Constants::DEFAULT_MAX_REACTIONS_PER_HOUR)
  @max_depth        = max_depth
  @cooldown_seconds = cooldown_seconds
  @max_per_hour     = max_per_hour
  @recent           = [] # Array of { rule_id:, event_id:, at: }
  @mutex            = Mutex.new
end

Instance Method Details

#allow?(rule_id:, depth:, event_id: nil) ⇒ Boolean



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/legion/extensions/react/helpers/loop_breaker.rb', line 18

def allow?(rule_id:, depth:, event_id: nil)
  return false if depth > @max_depth

  @mutex.synchronize do
    prune_old_entries
    return false if @recent.size >= @max_per_hour

    if event_id && @cooldown_seconds.positive?
      duplicate = @recent.any? do |r|
        r[:rule_id] == rule_id && r[:event_id] == event_id
      end
      return false if duplicate
    end

    true
  end
end

#reactions_this_hourObject



42
43
44
45
46
47
# File 'lib/legion/extensions/react/helpers/loop_breaker.rb', line 42

def reactions_this_hour
  @mutex.synchronize do
    prune_old_entries
    @recent.size
  end
end

#record(rule_id:, event_id:) ⇒ Object



36
37
38
39
40
# File 'lib/legion/extensions/react/helpers/loop_breaker.rb', line 36

def record(rule_id:, event_id:)
  @mutex.synchronize do
    @recent << { rule_id: rule_id, event_id: event_id, at: Time.now }
  end
end

#statsObject



49
50
51
52
53
54
# File 'lib/legion/extensions/react/helpers/loop_breaker.rb', line 49

def stats
  @mutex.synchronize do
    prune_old_entries
    { reactions_this_hour: @recent.size, max_per_hour: @max_per_hour }
  end
end