eye 0.8.pre2 → 0.8.rc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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