eye 0.8.pre2 → 0.8.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +141 -0
  3. data/.travis.yml +5 -3
  4. data/README.md +1 -2
  5. data/Rakefile +5 -5
  6. data/bin/leye +9 -4
  7. data/bin/loader_eye +14 -15
  8. data/examples/custom_check.eye +24 -0
  9. data/examples/custom_trigger.eye +3 -1
  10. data/examples/delayed_job.eye +3 -3
  11. data/examples/dependency.eye +10 -11
  12. data/examples/leye_example/Eyefile +10 -0
  13. data/examples/notify.eye +3 -4
  14. data/examples/plugin/main.eye +5 -5
  15. data/examples/plugin/plugin.rb +10 -2
  16. data/examples/process_thin.rb +8 -8
  17. data/examples/processes/em.rb +18 -12
  18. data/examples/processes/forking.rb +5 -5
  19. data/examples/processes/sample.rb +46 -44
  20. data/examples/puma.eye +9 -8
  21. data/examples/rbenv.eye +5 -5
  22. data/examples/sidekiq.eye +3 -3
  23. data/examples/stress_test.eye +4 -4
  24. data/examples/syslog.eye +1 -1
  25. data/examples/test.eye +1 -2
  26. data/examples/thin-farm.eye +7 -8
  27. data/examples/triggers.eye +13 -15
  28. data/examples/unicorn.eye +12 -13
  29. data/eye.gemspec +14 -12
  30. data/lib/eye.rb +2 -3
  31. data/lib/eye/application.rb +5 -6
  32. data/lib/eye/checker.rb +36 -19
  33. data/lib/eye/checker/children_count.rb +1 -1
  34. data/lib/eye/checker/file_ctime.rb +1 -1
  35. data/lib/eye/checker/http.rb +13 -15
  36. data/lib/eye/checker/nop.rb +1 -0
  37. data/lib/eye/checker/socket.rb +60 -63
  38. data/lib/eye/checker/ssl_socket.rb +5 -5
  39. data/lib/eye/child_process.rb +6 -4
  40. data/lib/eye/cli.rb +50 -41
  41. data/lib/eye/cli/commands.rb +4 -5
  42. data/lib/eye/cli/render.rb +61 -41
  43. data/lib/eye/cli/server.rb +19 -16
  44. data/lib/eye/client.rb +1 -0
  45. data/lib/eye/config.rb +19 -19
  46. data/lib/eye/controller.rb +2 -3
  47. data/lib/eye/controller/commands.rb +1 -1
  48. data/lib/eye/controller/helpers.rb +2 -2
  49. data/lib/eye/controller/load.rb +18 -12
  50. data/lib/eye/controller/options.rb +1 -5
  51. data/lib/eye/controller/send_command.rb +21 -23
  52. data/lib/eye/controller/status.rb +17 -15
  53. data/lib/eye/dsl.rb +3 -0
  54. data/lib/eye/dsl/application_opts.rb +4 -3
  55. data/lib/eye/dsl/chain.rb +2 -2
  56. data/lib/eye/dsl/child_process_opts.rb +3 -3
  57. data/lib/eye/dsl/config_opts.rb +7 -7
  58. data/lib/eye/dsl/group_opts.rb +3 -3
  59. data/lib/eye/dsl/helpers.rb +1 -1
  60. data/lib/eye/dsl/main.rb +4 -3
  61. data/lib/eye/dsl/opts.rb +31 -28
  62. data/lib/eye/dsl/process_opts.rb +13 -7
  63. data/lib/eye/dsl/pure_opts.rb +13 -9
  64. data/lib/eye/dsl/validation.rb +48 -35
  65. data/lib/eye/group.rb +20 -6
  66. data/lib/eye/group/chain.rb +6 -6
  67. data/lib/eye/loader.rb +1 -1
  68. data/lib/eye/local.rb +9 -4
  69. data/lib/eye/logger.rb +11 -4
  70. data/lib/eye/notify.rb +10 -6
  71. data/lib/eye/notify/jabber.rb +1 -1
  72. data/lib/eye/notify/mail.rb +2 -2
  73. data/lib/eye/notify/slack.rb +4 -3
  74. data/lib/eye/process.rb +2 -0
  75. data/lib/eye/process/children.rb +4 -4
  76. data/lib/eye/process/commands.rb +28 -31
  77. data/lib/eye/process/config.rb +21 -19
  78. data/lib/eye/process/data.rb +11 -9
  79. data/lib/eye/process/monitor.rb +30 -29
  80. data/lib/eye/process/notify.rb +10 -10
  81. data/lib/eye/process/scheduler.rb +36 -31
  82. data/lib/eye/process/states.rb +5 -4
  83. data/lib/eye/process/states_history.rb +9 -3
  84. data/lib/eye/process/system.rb +5 -4
  85. data/lib/eye/process/trigger.rb +1 -5
  86. data/lib/eye/process/watchers.rb +6 -9
  87. data/lib/eye/reason.rb +4 -1
  88. data/lib/eye/server.rb +2 -1
  89. data/lib/eye/system.rb +16 -13
  90. data/lib/eye/system_resources.rb +13 -8
  91. data/lib/eye/trigger.rb +18 -16
  92. data/lib/eye/trigger/check_dependency.rb +7 -4
  93. data/lib/eye/trigger/flapping.rb +24 -7
  94. data/lib/eye/trigger/starting_guard.rb +7 -6
  95. data/lib/eye/trigger/stop_children.rb +2 -2
  96. data/lib/eye/trigger/transition.rb +1 -1
  97. data/lib/eye/trigger/wait_dependency.rb +3 -2
  98. data/lib/eye/utils.rb +4 -3
  99. data/lib/eye/utils/alive_array.rb +9 -4
  100. data/lib/eye/utils/celluloid_chain.rb +12 -10
  101. data/lib/eye/utils/mini_active_support.rb +16 -16
  102. data/lib/eye/utils/pmap.rb +2 -0
  103. data/lib/eye/utils/tail.rb +2 -2
  104. metadata +34 -4
  105. data/lib/eye/utils/leak_19.rb +0 -10
@@ -1,4 +1,5 @@
1
1
  class Eye::Trigger
2
+
2
3
  include Eye::Dsl::Validation
3
4
 
4
5
  autoload :Flapping, 'eye/trigger/flapping'
@@ -8,19 +9,18 @@ class Eye::Trigger
8
9
  autoload :CheckDependency, 'eye/trigger/check_dependency'
9
10
  autoload :StartingGuard, 'eye/trigger/starting_guard'
10
11
 
11
- TYPES = {:flapping => 'Flapping', :transition => 'Transition', :stop_children => 'StopChildren',
12
- :wait_dependency => 'WaitDependency', :check_dependency => 'CheckDependency', :starting_guard => 'StartingGuard'
13
- }
12
+ TYPES = { flapping: 'Flapping', transition: 'Transition', stop_children: 'StopChildren',
13
+ wait_dependency: 'WaitDependency', check_dependency: 'CheckDependency', starting_guard: 'StartingGuard' }
14
14
 
15
15
  attr_reader :message, :options, :process
16
16
 
17
17
  def self.name_and_class(type)
18
18
  type = type.to_sym
19
- return {:name => type, :type => type} if TYPES[type]
19
+ return { name: type, type: type } if TYPES[type]
20
20
 
21
- if type =~ /\A(.*?)_?[0-9]+\z/
22
- ctype = $1.to_sym
23
- return {:name => type, :type => ctype} if TYPES[ctype]
21
+ if type =~ %r[\A(.*?)_?[0-9]+\z]
22
+ ctype = Regexp.last_match(1).to_sym
23
+ return { name: type, type: ctype } if TYPES[ctype]
24
24
  end
25
25
  end
26
26
 
@@ -36,7 +36,7 @@ class Eye::Trigger
36
36
  def self.create(process, options = {})
37
37
  get_class(options[:type]).new(process, options)
38
38
 
39
- rescue Exception, Timeout::Error => ex
39
+ rescue Object => ex
40
40
  log_ex(ex)
41
41
  nil
42
42
  end
@@ -72,7 +72,7 @@ class Eye::Trigger
72
72
 
73
73
  check(transition) if filter_transition(transition)
74
74
 
75
- rescue Exception, Timeout::Error => ex
75
+ rescue Object => ex
76
76
  if ex.class == Eye::Process::StateError
77
77
  raise ex
78
78
  else
@@ -92,7 +92,7 @@ class Eye::Trigger
92
92
  compare_state(trans.event, event)
93
93
  end
94
94
 
95
- def check(transition)
95
+ def check(_transition)
96
96
  raise NotImplementedError
97
97
  end
98
98
 
@@ -126,22 +126,24 @@ class Eye::Trigger
126
126
  end
127
127
 
128
128
  class Custom < Eye::Trigger
129
+
129
130
  def self.inherited(base)
130
131
  super
131
132
  register(base)
132
133
  end
134
+
133
135
  end
134
136
 
135
137
  private
136
138
 
137
139
  def compare_state(state_name, condition)
138
140
  case condition
139
- when Symbol
140
- state_name == condition
141
- when Array
142
- condition.include?(state_name)
143
- else
144
- true
141
+ when Symbol
142
+ state_name == condition
143
+ when Array
144
+ condition.include?(state_name)
145
+ else
146
+ true
145
147
  end
146
148
  end
147
149
 
@@ -1,4 +1,5 @@
1
1
  class Eye::Trigger::CheckDependency < Eye::Trigger
2
+
2
3
  param :names, [Array], true, 5
3
4
 
4
5
  def check(transition)
@@ -10,14 +11,16 @@ private
10
11
  def check_dependency(to)
11
12
  processes = names.map do |name|
12
13
  Eye::Control.find_nearest_process(name, process.group_name_pure, process.app_name)
13
- end.compact.select { |p| p.state_name != :unmonitored }
14
+ end
15
+
16
+ processes = processes.compact.select { |p| p.state_name != :unmonitored }
14
17
  return if processes.empty?
15
18
  processes = Eye::Utils::AliveArray.new(processes)
16
19
 
17
20
  act = case to
18
- when :down, :restarting; :restart
19
- when :stopping; :stop
20
- when :unmonitored; :unmonitor
21
+ when :down, :restarting then :restart
22
+ when :stopping then :stop
23
+ when :unmonitored then :unmonitor
21
24
  end
22
25
 
23
26
  if act
@@ -7,10 +7,12 @@ class Eye::Trigger::Flapping < Eye::Trigger
7
7
  param :within, [Float, Fixnum], true
8
8
  param :retry_in, [Float, Fixnum]
9
9
  param :retry_times, [Fixnum]
10
+ param :reretry_in, [Float, Fixnum]
11
+ param :reretry_times, [Fixnum]
10
12
 
11
13
  def initialize(*args)
12
14
  super
13
- @flapping_times = 0
15
+ clear_counters
14
16
  end
15
17
 
16
18
  def check(transition)
@@ -19,9 +21,16 @@ class Eye::Trigger::Flapping < Eye::Trigger
19
21
 
20
22
  private
21
23
 
24
+ def clear_counters
25
+ @retry_times = 0
26
+ @reretry_times = 0
27
+ end
28
+
22
29
  def good?
23
- states = process.states_history.states_for_period( within, @last_at )
24
- down_count = states.count{|st| st == :down }
30
+ down_count = 0
31
+ process.states_history.states_for_period(within, @last_at) do |s|
32
+ down_count += 1 if s[:state] == :down
33
+ end
25
34
 
26
35
  if down_count >= times
27
36
  @last_at = process.states_history.last_state_changed_at
@@ -38,10 +47,18 @@ private
38
47
  process.schedule :unmonitor, Eye::Reason::Flapping.new(:flapping)
39
48
 
40
49
  return unless retry_in
41
- return if retry_times && @flapping_times >= retry_times
42
-
43
- @flapping_times += 1
44
- process.schedule_in(retry_in.to_f, :conditional_start, Eye::Reason::Flapping.new('retry start after flapping'))
50
+ if !retry_times || (retry_times && @retry_times < retry_times)
51
+ @retry_times += 1
52
+ process.schedule_in(retry_in.to_f, :conditional_start, Eye::Reason::Flapping.new('retry start after flapping'))
53
+ else
54
+ if reretry_in
55
+ if !reretry_times || (reretry_times && @reretry_times < reretry_times)
56
+ @retry_times = 0
57
+ @reretry_times += 1
58
+ process.schedule_in(reretry_in.to_f, :conditional_start, Eye::Reason::Flapping.new('reretry start after flapping'))
59
+ end
60
+ end
61
+ end
45
62
  end
46
63
 
47
64
  end
@@ -33,32 +33,33 @@ class Eye::Trigger::StartingGuard < Eye::Trigger
33
33
  @reretry_count = 0
34
34
  return
35
35
  else
36
- info "false executed condition"
36
+ info 'false executed condition'
37
37
  end
38
38
 
39
39
  new_time = nil
40
40
  if every
41
41
  if times
42
- if (@retry_count < times)
42
+ if @retry_count < times
43
43
  new_time = Time.now + every
44
- process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new("starting_guard, retry start")
44
+ process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new('starting_guard, retry start')
45
45
  else
46
46
  @retry_count = 0
47
47
  @reretry_count += 1
48
48
  if retry_in && (!retry_times || (@reretry_count < retry_times))
49
49
  new_time = Time.now + retry_in
50
- process.schedule_in retry_in, :conditional_start, Eye::Reason::StartingGuard.new("starting_guard, reretry start")
50
+ process.schedule_in retry_in, :conditional_start, Eye::Reason::StartingGuard.new('starting_guard, reretry start')
51
51
  end
52
52
  end
53
53
  else
54
54
  new_time = Time.now + every
55
- process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new("starting_guard, retry start")
55
+ process.schedule_in every, :conditional_start, Eye::Reason::StartingGuard.new('starting_guard, retry start')
56
56
  end
57
57
  end
58
58
 
59
59
  retry_msg = new_time ? ", retry at '#{Eye::Utils.human_time2(new_time.to_i)}'" : ''
60
60
  process.switch :unmonitoring, Eye::Reason::StartingGuard.new("starting_guard, failed condition#{retry_msg}")
61
61
 
62
- raise Eye::Process::StateError.new("starting_guard, refused to start")
62
+ raise Eye::Process::StateError, 'starting_guard, refused to start'
63
63
  end
64
+
64
65
  end
@@ -9,9 +9,9 @@ class Eye::Trigger::StopChildren < Eye::Trigger
9
9
  # default on stopped, crashed
10
10
  param_default :event, [:stopped, :crashed]
11
11
 
12
- def check(trans)
12
+ def check(_trans)
13
13
  debug { 'stopping children' }
14
- process.children.pmap { |pid, c| c.stop }
14
+ process.children.pmap { |_pid, c| c.stop }
15
15
  end
16
16
 
17
17
  end
@@ -4,7 +4,7 @@ class Eye::Trigger::Transition < Eye::Trigger
4
4
 
5
5
  param :do, [Proc, Symbol]
6
6
 
7
- def check(trans)
7
+ def check(_trans)
8
8
  exec_proc :do
9
9
  end
10
10
 
@@ -1,4 +1,5 @@
1
1
  class Eye::Trigger::WaitDependency < Eye::Trigger
2
+
2
3
  param :names, [Array], true
3
4
  param :wait_timeout, [Numeric], nil, 15.seconds
4
5
  param :retry_after, [Numeric], nil, 1.minute
@@ -18,7 +19,7 @@ private
18
19
  processes = Eye::Utils::AliveArray.new(processes)
19
20
 
20
21
  processes.each do |p|
21
- if p.state_name != :up && (should_start == nil || should_start)
22
+ if p.state_name != :up && (should_start != false)
22
23
  p.schedule :start, Eye::Reason.new(:start_dependency)
23
24
  end
24
25
  end
@@ -42,7 +43,7 @@ private
42
43
  process.schedule_in retry_after, :start, Eye::Reason.new(:wait_dependency)
43
44
  end
44
45
 
45
- raise Eye::Process::StateError.new('stop transition because dependency is not up')
46
+ raise Eye::Process::StateError, 'stop transition because dependency is not up'
46
47
  end
47
48
  end
48
49
 
@@ -1,14 +1,15 @@
1
1
  require 'date'
2
2
 
3
3
  module Eye::Utils
4
+
4
5
  autoload :Tail, 'eye/utils/tail'
5
6
  autoload :AliveArray, 'eye/utils/alive_array'
6
7
  autoload :CelluloidChain, 'eye/utils/celluloid_chain'
7
8
 
8
9
  def self.deep_clone(value)
9
10
  case
10
- when value.is_a?(Array) then value.map{|v| deep_clone(v) }
11
- when value.is_a?(Hash) then value.inject({}){|r, (k, v)| r[ deep_clone(k) ] = deep_clone(v); r }
11
+ when value.is_a?(Array) then value.map { |v| deep_clone(v) }
12
+ when value.is_a?(Hash) then value.each_with_object({}) { |(k, v), r| r[deep_clone(k)] = deep_clone(v) }
12
13
  else value
13
14
  end
14
15
  end
@@ -47,7 +48,7 @@ module Eye::Utils
47
48
  env_vars = content.split("\n")
48
49
  h = {}
49
50
  env_vars.each do |e|
50
- e = e.gsub(/#.+$/, '').strip
51
+ e = e.gsub(%r[#.+$], '').strip
51
52
  next unless e.include?('=')
52
53
  k, v = e.split('=', 2)
53
54
  h[k] = v
@@ -1,20 +1,21 @@
1
1
  class Eye::Utils::AliveArray
2
+
2
3
  extend Forwardable
3
4
  include Enumerable
4
5
 
5
6
  def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?, :push,
6
- :flatten, :present?, :uniq!, :select!
7
+ :flatten, :present?, :uniq!, :select!
7
8
 
8
9
  def initialize(arr = [])
9
10
  @arr = arr
10
11
  end
11
12
 
12
13
  def each(&block)
13
- @arr.each{|elem| elem && elem.alive? && block[elem] }
14
+ @arr.each { |elem| elem && elem.alive? && block[elem] }
14
15
  end
15
16
 
16
17
  def to_a
17
- map{|x| x }
18
+ map { |x| x }
18
19
  end
19
20
 
20
21
  def full_size
@@ -33,6 +34,10 @@ class Eye::Utils::AliveArray
33
34
  self.class.new super
34
35
  end
35
36
 
37
+ def sort!
38
+ @arr.sort!
39
+ end
40
+
36
41
  def +(other)
37
42
  if other.is_a?(Eye::Utils::AliveArray)
38
43
  @arr += other.pure
@@ -54,4 +59,4 @@ class Eye::Utils::AliveArray
54
59
  end
55
60
  end
56
61
 
57
- end
62
+ end
@@ -1,6 +1,7 @@
1
1
  require 'celluloid'
2
2
 
3
3
  class Eye::Utils::CelluloidChain
4
+
4
5
  include Celluloid
5
6
 
6
7
  def initialize(target)
@@ -10,21 +11,21 @@ class Eye::Utils::CelluloidChain
10
11
  @target_class = @target.class
11
12
  end
12
13
 
13
- def add(method_name, *args, &block)
14
- @calls << {:method_name => method_name, :args => args, :block => block}
14
+ def add(method_name, *args)
15
+ @calls << { method_name: method_name, args: args }
15
16
  ensure_process
16
17
  end
17
18
 
18
- def add_wo_dups(method_name, *args, &block)
19
- h = {:method_name => method_name, :args => args, :block => block}
19
+ def add_wo_dups(method_name, *args)
20
+ h = { method_name: method_name, args: args }
20
21
  if @calls[-1] != h
21
22
  @calls << h
22
23
  ensure_process
23
24
  end
24
25
  end
25
26
 
26
- def add_wo_dups_current(method_name, *args, &block)
27
- h = {:method_name => method_name, :args => args, :block => block}
27
+ def add_wo_dups_current(method_name, *args)
28
+ h = { method_name: method_name, args: args }
28
29
  if !@calls.include?(h) && @call != h
29
30
  @calls << h
30
31
  ensure_process
@@ -36,14 +37,14 @@ class Eye::Utils::CelluloidChain
36
37
  end
37
38
 
38
39
  def names_list
39
- list.map{|el| el[:method_name].to_sym }
40
+ list.map { |el| el[:method_name].to_sym }
40
41
  end
41
42
 
42
43
  def clear
43
44
  @calls = []
44
45
  end
45
46
 
46
- alias :clear_pending_list :clear
47
+ alias_method :clear_pending_list, :clear
47
48
 
48
49
  # need, because of https://github.com/celluloid/celluloid/issues/22
49
50
  def inspect
@@ -64,8 +65,9 @@ private
64
65
  def process
65
66
  while @call = @calls.shift
66
67
  @running = true
67
- @target.send(@call[:method_name], *@call[:args], &@call[:block]) if @target.alive?
68
+ @target.send(@call[:method_name], *@call[:args]) if @target.alive?
68
69
  end
69
70
  @running = false
70
71
  end
71
- end
72
+
73
+ end
@@ -31,9 +31,9 @@ class String
31
31
  word = self.dup
32
32
  word.gsub!('::', '/')
33
33
  word.gsub!(/(?:([A-Za-z\d])|^)((?=a)b)(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
34
- word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
35
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
36
- word.tr!("-", "_")
34
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
35
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
36
+ word.tr!('-', '_')
37
37
  word.downcase!
38
38
  word
39
39
  end
@@ -53,32 +53,32 @@ class Numeric
53
53
  def percents
54
54
  self
55
55
  end
56
- alias :percent :percents
56
+ alias_method :percent, :percents
57
57
 
58
58
  def seconds
59
59
  self
60
60
  end
61
- alias :second :seconds
61
+ alias_method :second, :seconds
62
62
 
63
63
  def minutes
64
64
  self * 60
65
65
  end
66
- alias :minute :minutes
66
+ alias_method :minute, :minutes
67
67
 
68
68
  def hours
69
69
  self * 3600
70
70
  end
71
- alias :hour :hours
71
+ alias_method :hour, :hours
72
72
 
73
73
  def days
74
- self * 86400
74
+ self * 86_400
75
75
  end
76
- alias :day :days
76
+ alias_method :day, :days
77
77
 
78
78
  def weeks
79
- self * 86400 * 7
79
+ self * 86_400 * 7
80
80
  end
81
- alias :week :weeks
81
+ alias_method :week, :weeks
82
82
 
83
83
  def ago
84
84
  ::Time.now - self
@@ -87,25 +87,25 @@ class Numeric
87
87
  def bytes
88
88
  self
89
89
  end
90
- alias :byte :bytes
90
+ alias_method :byte, :bytes
91
91
 
92
92
  def kilobytes
93
93
  self * 1024
94
94
  end
95
- alias :kilobyte :kilobytes
95
+ alias_method :kilobyte, :kilobytes
96
96
 
97
97
  def megabytes
98
98
  self * 1024 * 1024
99
99
  end
100
- alias :megabyte :megabytes
100
+ alias_method :megabyte, :megabytes
101
101
 
102
102
  def gigabytes
103
103
  self * 1024 * 1024 * 1024
104
104
  end
105
- alias :gigabyte :gigabytes
105
+ alias_method :gigabyte, :gigabytes
106
106
 
107
107
  def terabytes
108
108
  self * 1024 * 1024 * 1024 * 1024
109
109
  end
110
- alias :terabyte :terabytes
110
+ alias_method :terabyte, :terabytes
111
111
  end