Class: Bluepill::Triggers::Flapping

Inherits:
Bluepill::Trigger show all
Defined in:
lib/bluepill/triggers/flapping.rb

Constant Summary collapse

TRIGGER_STATES =
[:starting, :restarting]
PARAMS =
[:times, :within, :retry_in]

Instance Attribute Summary collapse

Attributes inherited from Bluepill::Trigger

#logger, #mutex, #process, #scheduled_events

Instance Method Summary collapse

Methods inherited from Bluepill::Trigger

[], #cancel_all_events, #dispatch!, inherited, #schedule_event

Constructor Details

#initialize(process, options = {}) ⇒ Flapping

Returns a new instance of Flapping.



11
12
13
14
15
16
17
18
19
20
# File 'lib/bluepill/triggers/flapping.rb', line 11

def initialize(process, options = {})
  options.reverse_merge!(:times => 5, :within => 1, :retry_in => 5)
  
  options.each_pair do |name, val|
    instance_variable_set("@#{name}", val) if PARAMS.include?(name)
  end
  
  @timeline = Util::RotationalArray.new(@times)
  super
end

Instance Attribute Details

#timelineObject (readonly)

Returns the value of attribute timeline.



9
10
11
# File 'lib/bluepill/triggers/flapping.rb', line 9

def timeline
  @timeline
end

Instance Method Details

#check_flappingObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/bluepill/triggers/flapping.rb', line 34

def check_flapping
  num_occurances = (@timeline.nitems == self.times)
  
  # The process has not flapped if we haven't encountered enough incidents
  return unless num_occurances
  
  # Check if the incident happend within the timeframe
  duration = (@timeline.last - @timeline.first) <= self.within
  
  if duration
    self.logger.info "Flapping detected: retrying in #{self.retry_in} seconds"
    
    self.schedule_event(:start, self.retry_in)
    
    # this happens in the process' thread so we don't have to worry about concurrency issues with this event
    self.dispatch!(:unmonitor)
    
    @timeline.clear
    
    # This will prevent a transition from happening in the process state_machine
    throw :halt
  end
end

#notify(transition) ⇒ Object



22
23
24
25
26
27
# File 'lib/bluepill/triggers/flapping.rb', line 22

def notify(transition)
  if TRIGGER_STATES.include?(transition.to_name)
    self.timeline << Time.now.to_i
    self.check_flapping
  end
end

#reset!Object



29
30
31
32
# File 'lib/bluepill/triggers/flapping.rb', line 29

def reset!
  @timeline.clear
  super
end