eye 0.7 → 0.8.celluloid15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +141 -0
  3. data/.travis.yml +5 -3
  4. data/CHANGES.md +9 -1
  5. data/README.md +5 -2
  6. data/Rakefile +6 -6
  7. data/bin/leye +9 -4
  8. data/bin/loader_eye +14 -15
  9. data/examples/custom_check.eye +24 -0
  10. data/examples/custom_trigger.eye +30 -0
  11. data/examples/delayed_job.eye +3 -3
  12. data/examples/dependency.eye +10 -11
  13. data/examples/leye_example/Eyefile +10 -0
  14. data/examples/notify.eye +3 -4
  15. data/examples/plugin/main.eye +5 -5
  16. data/examples/plugin/plugin.rb +10 -2
  17. data/examples/process_thin.rb +8 -8
  18. data/examples/processes/em.rb +18 -12
  19. data/examples/processes/forking.rb +5 -5
  20. data/examples/processes/sample.rb +46 -44
  21. data/examples/puma.eye +9 -8
  22. data/examples/rbenv.eye +5 -5
  23. data/examples/sidekiq.eye +3 -3
  24. data/examples/stress_test.eye +4 -4
  25. data/examples/syslog.eye +1 -1
  26. data/examples/test.eye +1 -2
  27. data/examples/thin-farm.eye +7 -8
  28. data/examples/triggers.eye +13 -15
  29. data/examples/unicorn.eye +12 -13
  30. data/eye.gemspec +16 -14
  31. data/lib/eye.rb +2 -3
  32. data/lib/eye/application.rb +5 -6
  33. data/lib/eye/checker.rb +44 -25
  34. data/lib/eye/checker/children_count.rb +1 -1
  35. data/lib/eye/checker/file_ctime.rb +1 -1
  36. data/lib/eye/checker/http.rb +13 -15
  37. data/lib/eye/checker/nop.rb +1 -0
  38. data/lib/eye/checker/socket.rb +60 -63
  39. data/lib/eye/checker/ssl_socket.rb +5 -5
  40. data/lib/eye/child_process.rb +6 -4
  41. data/lib/eye/cli.rb +74 -46
  42. data/lib/eye/cli/commands.rb +4 -5
  43. data/lib/eye/cli/render.rb +61 -41
  44. data/lib/eye/cli/server.rb +19 -16
  45. data/lib/eye/client.rb +1 -0
  46. data/lib/eye/config.rb +36 -33
  47. data/lib/eye/controller.rb +2 -3
  48. data/lib/eye/controller/commands.rb +1 -1
  49. data/lib/eye/controller/helpers.rb +2 -2
  50. data/lib/eye/controller/load.rb +19 -17
  51. data/lib/eye/controller/options.rb +1 -5
  52. data/lib/eye/controller/send_command.rb +21 -23
  53. data/lib/eye/controller/status.rb +17 -14
  54. data/lib/eye/dsl.rb +6 -1
  55. data/lib/eye/dsl/application_opts.rb +4 -3
  56. data/lib/eye/dsl/chain.rb +2 -2
  57. data/lib/eye/dsl/child_process_opts.rb +3 -3
  58. data/lib/eye/dsl/config_opts.rb +7 -7
  59. data/lib/eye/dsl/group_opts.rb +3 -3
  60. data/lib/eye/dsl/helpers.rb +1 -1
  61. data/lib/eye/dsl/main.rb +4 -3
  62. data/lib/eye/dsl/opts.rb +31 -28
  63. data/lib/eye/dsl/process_opts.rb +13 -7
  64. data/lib/eye/dsl/pure_opts.rb +13 -9
  65. data/lib/eye/dsl/validation.rb +48 -35
  66. data/lib/eye/group.rb +23 -8
  67. data/lib/eye/group/chain.rb +6 -6
  68. data/lib/eye/loader.rb +3 -3
  69. data/lib/eye/local.rb +9 -4
  70. data/lib/eye/logger.rb +11 -4
  71. data/lib/eye/notify.rb +10 -6
  72. data/lib/eye/notify/jabber.rb +1 -1
  73. data/lib/eye/notify/mail.rb +2 -2
  74. data/lib/eye/notify/slack.rb +4 -3
  75. data/lib/eye/process.rb +2 -0
  76. data/lib/eye/process/children.rb +4 -4
  77. data/lib/eye/process/commands.rb +38 -39
  78. data/lib/eye/process/config.rb +22 -16
  79. data/lib/eye/process/controller.rb +5 -19
  80. data/lib/eye/process/data.rb +11 -9
  81. data/lib/eye/process/monitor.rb +86 -76
  82. data/lib/eye/process/notify.rb +10 -10
  83. data/lib/eye/process/scheduler.rb +36 -31
  84. data/lib/eye/process/states.rb +7 -5
  85. data/lib/eye/process/states_history.rb +9 -3
  86. data/lib/eye/process/system.rb +35 -20
  87. data/lib/eye/process/trigger.rb +1 -5
  88. data/lib/eye/process/watchers.rb +12 -9
  89. data/lib/eye/reason.rb +4 -1
  90. data/lib/eye/server.rb +3 -2
  91. data/lib/eye/system.rb +22 -15
  92. data/lib/eye/system_resources.rb +17 -8
  93. data/lib/eye/trigger.rb +18 -16
  94. data/lib/eye/trigger/check_dependency.rb +7 -4
  95. data/lib/eye/trigger/flapping.rb +24 -7
  96. data/lib/eye/trigger/starting_guard.rb +7 -6
  97. data/lib/eye/trigger/stop_children.rb +2 -2
  98. data/lib/eye/trigger/transition.rb +1 -1
  99. data/lib/eye/trigger/wait_dependency.rb +3 -2
  100. data/lib/eye/utils.rb +4 -3
  101. data/lib/eye/utils/alive_array.rb +9 -4
  102. data/lib/eye/utils/celluloid_chain.rb +12 -10
  103. data/lib/eye/utils/mini_active_support.rb +16 -16
  104. data/lib/eye/utils/pmap.rb +2 -0
  105. data/lib/eye/utils/tail.rb +2 -2
  106. metadata +39 -8
  107. data/lib/eye/utils/leak_19.rb +0 -10
@@ -7,21 +7,21 @@ class Eye::Dsl::ProcessOpts < Eye::Dsl::Opts
7
7
  Eye::Utils.deep_merge!(@config[:monitor_children], opts.config)
8
8
  end
9
9
 
10
- alias xmonitor_children nop
10
+ alias_method :xmonitor_children, :nop
11
11
 
12
12
  def application
13
13
  parent.try(:parent)
14
14
  end
15
- alias app application
16
- alias group parent
15
+ alias_method :app, :application
16
+ alias_method :group, :parent
17
17
 
18
18
  def depend_on(names, opts = {})
19
19
  names = Array(names).map(&:to_s)
20
- trigger("wait_dependency_#{unique_num}", {:names => names}.merge(opts))
20
+ trigger("wait_dependency_#{unique_num}", { names: names }.merge(opts))
21
21
  nm = @config[:name]
22
22
  names.each do |name|
23
23
  parent.process(name) do
24
- trigger("check_dependency_#{unique_num}", :names => [ nm ] )
24
+ trigger("check_dependency_#{unique_num}", names: [nm])
25
25
  end
26
26
  end
27
27
 
@@ -31,8 +31,14 @@ class Eye::Dsl::ProcessOpts < Eye::Dsl::Opts
31
31
  private
32
32
 
33
33
  def unique_num
34
- $unique_num ||= 0
35
- $unique_num += 1
34
+ self.class.unique_num ||= 0
35
+ self.class.unique_num += 1
36
+ end
37
+
38
+ class << self
39
+
40
+ attr_accessor :unique_num
41
+
36
42
  end
37
43
 
38
44
  end
@@ -11,7 +11,7 @@ class Eye::Dsl::PureOpts
11
11
  end
12
12
 
13
13
  if types
14
- good_type = Array(types).any?{|type| arg.is_a?(type) } || arg.nil?
14
+ good_type = Array(types).any? { |type| arg.is_a?(type) } || arg.nil?
15
15
  raise Eye::Dsl::Error, "bad :#{opt} value #{arg.inspect}, type should be #{types.inspect}" unless good_type
16
16
  end
17
17
 
@@ -19,7 +19,7 @@ class Eye::Dsl::PureOpts
19
19
  end
20
20
 
21
21
  define_method("get_#{opt}") do
22
- @config[ opt.to_sym ]
22
+ @config[opt.to_sym]
23
23
  end
24
24
 
25
25
  define_method(opt) do |*args|
@@ -37,7 +37,7 @@ class Eye::Dsl::PureOpts
37
37
  end
38
38
  end
39
39
 
40
- self.send :include, m
40
+ send :include, m
41
41
  end
42
42
 
43
43
  attr_reader :name, :full_name
@@ -50,7 +50,7 @@ class Eye::Dsl::PureOpts
50
50
  if parent
51
51
  @parent = parent
52
52
  if merge_parent_config
53
- @config = Eye::Utils::deep_clone(parent.config)
53
+ @config = Eye::Utils.deep_clone(parent.config)
54
54
  parent.not_seed_options.each { |opt| @config.delete(opt) }
55
55
  else
56
56
  @config = {}
@@ -76,7 +76,7 @@ class Eye::Dsl::PureOpts
76
76
  end
77
77
 
78
78
  def with_condition(cond = true, &block)
79
- self.instance_eval(&block) if cond && block
79
+ instance_eval(&block) if cond && block
80
80
  end
81
81
 
82
82
  def use(proc, *args)
@@ -84,18 +84,18 @@ class Eye::Dsl::PureOpts
84
84
  self.class.with_parsed_file(proc) do |path|
85
85
  if File.exist?(path)
86
86
  Eye::Dsl.debug { "=> load #{path}" }
87
- self.instance_eval(File.read(path))
87
+ instance_eval(File.read(path))
88
88
  Eye::Dsl.debug { "<= load #{path}" }
89
89
  end
90
90
  end
91
91
  else
92
92
  ie = if args.present?
93
- lambda{|i| proc[i, *args] }
93
+ ->(i) { proc[i, *args] }
94
94
  else
95
95
  proc
96
96
  end
97
97
 
98
- self.instance_eval(&ie)
98
+ instance_eval(&ie)
99
99
  end
100
100
  end
101
101
 
@@ -104,8 +104,12 @@ class Eye::Dsl::PureOpts
104
104
  def self.with_parsed_file(file_name)
105
105
  saved_parsed_filename = Eye.parsed_filename
106
106
 
107
+ real_filename = if Eye.parsed_filename && File.symlink?(Eye.parsed_filename)
108
+ File.readlink(Eye.parsed_filename)
109
+ else
110
+ Eye.parsed_filename
111
+ end
107
112
 
108
- real_filename = Eye.parsed_filename && File.symlink?(Eye.parsed_filename) ? File.readlink(Eye.parsed_filename) : Eye.parsed_filename
109
113
  dirname = File.dirname(real_filename) rescue nil
110
114
  path = File.expand_path(file_name, dirname)
111
115
 
@@ -1,4 +1,5 @@
1
1
  module Eye::Dsl::Validation
2
+
2
3
  def self.included(base)
3
4
  base.extend(ClassMethods)
4
5
  end
@@ -6,25 +7,37 @@ module Eye::Dsl::Validation
6
7
  class Error < Exception; end
7
8
 
8
9
  module ClassMethods
10
+
9
11
  def inherited(subclass)
10
- subclass.validates = self.validates.clone
11
- subclass.should_bes = self.should_bes.clone
12
- subclass.defaults = self.defaults.clone
13
- subclass.variants = self.variants.clone
12
+ subclass.validates = validates.clone
13
+ subclass.should_bes = should_bes.clone
14
+ subclass.defaults = defaults.clone
15
+ subclass.variants = variants.clone
14
16
  end
15
17
 
16
18
  attr_accessor :validates, :should_bes, :defaults, :variants
17
19
 
18
- def validates; @validates ||= {}; end
19
- def should_bes; @should_bes ||= []; end
20
- def defaults; @defaults ||= {}; end
21
- def variants; @variants ||= {}; end
20
+ def validates
21
+ @validates ||= {}
22
+ end
23
+
24
+ def should_bes
25
+ @should_bes ||= []
26
+ end
27
+
28
+ def defaults
29
+ @defaults ||= {}
30
+ end
31
+
32
+ def variants
33
+ @variants ||= {}
34
+ end
22
35
 
23
36
  def param(param, types = [], should_be = false, default = nil, variants = nil)
24
37
  param = param.to_sym
25
38
 
26
- self.validates[param] = types
27
- self.should_bes << param if should_be
39
+ validates[param] = types
40
+ should_bes << param if should_be
28
41
  param_default(param, default)
29
42
  self.variants[param] = variants
30
43
 
@@ -55,38 +68,38 @@ module Eye::Dsl::Validation
55
68
  end
56
69
 
57
70
  def validate(options = {})
58
- options.each do |param, value|
59
- param = param.to_sym
60
- types = validates[param]
61
- unless types
62
- if param != :type
63
- raise Error, "#{self.name} unknown param :#{param} value #{value.inspect}"
64
- end
65
- end
71
+ options.each { |param, value| validate_param(param, value) }
66
72
 
67
- if self.variants[param]
68
- if value && !value.is_a?(Proc)
69
- if value.is_a?(Array)
70
- if (value - self.variants[param]).present?
71
- raise Error, "#{value.inspect} should be within #{self.variants[param].inspect}"
72
- end
73
- elsif !self.variants[param].include?(value)
74
- raise Error, "#{value.inspect} should be within #{self.variants[param].inspect}"
75
- end
76
- end
77
- end
73
+ should_bes.each do |param|
74
+ raise Error, "#{name} for param :#{param} value should be" unless options[param.to_sym] || defaults[param.to_sym]
75
+ end
76
+ end
78
77
 
79
- next if types.blank?
78
+ def validate_param(param, value)
79
+ param = param.to_sym
80
+ types = validates[param]
81
+ if !types && param != :type
82
+ raise Error, "#{name} unknown param :#{param} value #{value.inspect}"
83
+ end
80
84
 
81
- types = Array(types)
82
- good = types.any?{|type| value.is_a?(type) }
83
- raise Error, "#{self.name} bad param :#{param} value #{value.inspect}, type #{types.inspect}" unless good
85
+ if variants[param] && value && !value.is_a?(Proc)
86
+ if value.is_a?(Array)
87
+ value = value.reject { |v| v.is_a?(Proc) }
88
+ if (value - variants[param]).present?
89
+ raise Error, "#{value.inspect} should be within #{variants[param].inspect}"
90
+ end
91
+ elsif !variants[param].include?(value)
92
+ raise Error, "#{value.inspect} should be within #{variants[param].inspect}"
93
+ end
84
94
  end
85
95
 
86
- should_bes.each do |param|
87
- raise Error, "#{self.name} for param :#{param} value should be" unless options[param.to_sym] || defaults[param.to_sym]
96
+ if types.present?
97
+ types = Array(types)
98
+ good = types.any? { |type| value.is_a?(type) }
99
+ raise Error, "#{name} bad param :#{param} value #{value.inspect}, type #{types.inspect}" unless good
88
100
  end
89
101
  end
102
+
90
103
  end
91
104
 
92
105
  end
@@ -1,6 +1,7 @@
1
1
  require 'celluloid'
2
2
 
3
3
  class Eye::Group
4
+
4
5
  include Celluloid
5
6
 
6
7
  autoload :Chain, 'eye/group/chain'
@@ -44,12 +45,12 @@ class Eye::Group
44
45
  @processes = @processes.sort_by(&:name)
45
46
  end
46
47
 
47
- def status_data(debug = false)
48
- plist = @processes.map{|p| p.status_data(debug) }
48
+ def status_data(opts = {})
49
+ plist = @processes.map { |p| p.status_data(opts) }
49
50
 
50
51
  h = { name: name, type: :group, subtree: plist }
51
52
 
52
- h[:debug] = debug_data if debug
53
+ h[:debug] = debug_data if opts[:debug]
53
54
 
54
55
  # show current chain
55
56
  if current_scheduled_command
@@ -68,16 +69,17 @@ class Eye::Group
68
69
  end
69
70
 
70
71
  def status_data_short
71
- h = Hash.new
72
+ h = {}
72
73
  @processes.each do |p|
73
- h[p.state] ||= 0
74
- h[p.state] += 1
74
+ state = p.state
75
+ h[state] ||= 0
76
+ h[state] += 1
75
77
  end
76
78
  { name: (@name == '__default__' ? 'default' : @name), type: :group, states: h }
77
79
  end
78
80
 
79
81
  def debug_data
80
- {:queue => scheduler_actions_list, :chain => chain_status}
82
+ { queue: scheduler_actions_list, chain: chain_status }
81
83
  end
82
84
 
83
85
  def send_command(command, *args)
@@ -144,10 +146,23 @@ class Eye::Group
144
146
  @processes.include?(obj)
145
147
  end
146
148
 
149
+ # to sort groups
150
+ def <=>(other)
151
+ if hidden
152
+ 1
153
+ else
154
+ if other.hidden
155
+ -1
156
+ else
157
+ name <=> other.name
158
+ end
159
+ end
160
+ end
161
+
147
162
  private
148
163
 
149
164
  def async_schedule(command, *args)
150
- info "send to all processes #{command} #{args.present? ? args*',' : nil}"
165
+ info "send to all processes #{command} #{args.present? ? args * ',' : nil}"
151
166
 
152
167
  @processes.each do |process|
153
168
  process.send_command(command, *args) unless process.skip_group_action?(command)
@@ -11,7 +11,7 @@ private
11
11
 
12
12
  started_at = Time.now
13
13
 
14
- @processes.each do | process |
14
+ @processes.each do |process|
15
15
  if process.skip_group_action?(command)
16
16
  @chain_processes_current = @chain_processes_current.to_i + 1
17
17
  next
@@ -44,7 +44,7 @@ private
44
44
  # sync command, with waiting
45
45
  # this is very hackety, because call method of the process without its scheduler
46
46
  # need to provide some scheduler future
47
- process.last_scheduled_reason = self.last_scheduled_reason
47
+ process.last_scheduled_reason = last_scheduled_reason
48
48
  process.send(command, *args)
49
49
  else
50
50
  # async command
@@ -54,7 +54,7 @@ private
54
54
 
55
55
  def chain_status
56
56
  if @config[:chain]
57
- [:start, :restart].map{|c| @config[:chain][c].try(:[], :grace) }
57
+ [:start, :restart].map { |c| @config[:chain][c].try(:[], :grace) }
58
58
  end
59
59
  end
60
60
 
@@ -67,7 +67,7 @@ private
67
67
  DEFAULT_CHAIN = 0.2
68
68
 
69
69
  def chain_options(command)
70
- command = :start if command == :monitor # hack for monitor command, work as start
70
+ command = :start if command == :monitor # HACK: for monitor command, work as start
71
71
 
72
72
  if @config[:chain] && @config[:chain][command]
73
73
  type = @config[:chain][command].try :[], :type
@@ -76,10 +76,10 @@ private
76
76
  grace = @config[:chain][command].try :[], :grace
77
77
  grace = grace ? (grace.to_f rescue DEFAULT_CHAIN) : DEFAULT_CHAIN
78
78
 
79
- {:type => type, :grace => grace}
79
+ { type: type, grace: grace }
80
80
  else
81
81
  # default chain case
82
- {:type => :async, :grace => DEFAULT_CHAIN}
82
+ { type: :async, grace: DEFAULT_CHAIN }
83
83
  end
84
84
  end
85
85
 
@@ -1,10 +1,10 @@
1
1
  # add gems to $: by `gem` method
2
2
  # this is only way when install eye as system wide
3
3
 
4
- gem 'celluloid', '~> 0.16.0'
5
- gem 'celluloid-io', '~> 0.16.0'
4
+ gem 'celluloid', '~> 0.15.0'
5
+ gem 'celluloid-io', '~> 0.15.0'
6
6
  gem 'nio4r'
7
7
  gem 'timers'
8
8
 
9
9
  gem 'state_machine'
10
- gem 'sigar', '~> 0.7.2'
10
+ gem 'sigar', '~> 0.7.3'
@@ -1,7 +1,9 @@
1
1
  require 'fileutils'
2
2
 
3
3
  module Eye::Local
4
+
4
5
  class << self
6
+
5
7
  def dir
6
8
  @dir ||= begin
7
9
  if root?
@@ -28,7 +30,7 @@ module Eye::Local
28
30
 
29
31
  def home
30
32
  h = ENV['EYE_HOME'] || ENV['HOME']
31
- raise "HOME undefined, should be HOME or EYE_HOME environment" unless h
33
+ raise 'HOME undefined, should be HOME or EYE_HOME environment' unless h
32
34
  h
33
35
  end
34
36
 
@@ -37,7 +39,7 @@ module Eye::Local
37
39
  end
38
40
 
39
41
  def ensure_eye_dir
40
- FileUtils.mkdir_p(dir)
42
+ FileUtils.mkdir_p(dir) unless ENV['EYE_SOCK'] && ENV['EYE_PID']
41
43
  end
42
44
 
43
45
  def socket_path
@@ -72,7 +74,7 @@ module Eye::Local
72
74
  end
73
75
 
74
76
  def eyefile
75
- @eyefile ||= find_eyefile('.')
77
+ @eyefile ||= find_eyefile(ENV['EYE_HOME'] || '.')
76
78
  end
77
79
 
78
80
  def find_eyefile(start_from_dir)
@@ -85,10 +87,13 @@ module Eye::Local
85
87
  until !File.directory?(current) || current == previous
86
88
  filename = File.join(current, 'Eyefile')
87
89
  return filename if File.file?(filename)
88
- current, previous = File.expand_path('..', current), current
90
+ previous = current
91
+ current = File.expand_path('..', current)
89
92
  end
90
93
  end
91
94
 
92
95
  attr_accessor :local_runner
96
+
93
97
  end
98
+
94
99
  end
@@ -1,23 +1,27 @@
1
1
  require 'logger'
2
2
 
3
3
  class Eye::Logger
4
+
4
5
  attr_accessor :prefix, :subprefix
5
6
 
6
7
  class InnerLogger < Logger
8
+
7
9
  FORMAT = '%d.%m.%Y %H:%M:%S'
8
10
 
9
11
  def initialize(*args)
10
12
  super
11
13
 
12
- self.formatter = Proc.new do |s, d, p, m|
14
+ self.formatter = proc do |s, d, _p, m|
13
15
  "#{d.strftime(FORMAT)} #{s.ljust(5)} -- #{m}\n"
14
16
  end
15
17
  end
18
+
16
19
  end
17
20
 
18
21
  module ObjectExt
22
+
19
23
  def logger_tag
20
- [Class, Module].include?(self.class) ? to_s : "<#{self.class.to_s}>"
24
+ [Class, Module].include?(self.class) ? to_s : "<#{self.class}>"
21
25
  end
22
26
 
23
27
  def logger_sub_tag
@@ -38,6 +42,7 @@ class Eye::Logger
38
42
  error "#{ex.message} #{ex.backtrace}"
39
43
  # notify here?
40
44
  end
45
+
41
46
  end
42
47
 
43
48
  Logger::Severity.constants.each do |level|
@@ -57,6 +62,7 @@ class Eye::Logger
57
62
  end
58
63
 
59
64
  class << self
65
+
60
66
  attr_reader :dev, :log_level, :args
61
67
 
62
68
  def link_logger(dev, *args)
@@ -74,7 +80,7 @@ class Eye::Logger
74
80
  @inner_logger = dev
75
81
  end
76
82
 
77
- @inner_logger.level = self.log_level || Logger::INFO
83
+ @inner_logger.level = log_level || Logger::INFO
78
84
 
79
85
  rescue Exception
80
86
  @inner_logger = nil
@@ -88,12 +94,13 @@ class Eye::Logger
88
94
 
89
95
  def log_level=(level)
90
96
  @log_level = level
91
- @inner_logger.level = self.log_level if @inner_logger
97
+ @inner_logger.level = log_level if @inner_logger
92
98
  end
93
99
 
94
100
  def inner_logger
95
101
  @inner_logger ||= InnerLogger.new(nil)
96
102
  end
103
+
97
104
  end
98
105
 
99
106
  private