eye 0.7 → 0.8.celluloid15
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +141 -0
- data/.travis.yml +5 -3
- data/CHANGES.md +9 -1
- data/README.md +5 -2
- data/Rakefile +6 -6
- data/bin/leye +9 -4
- data/bin/loader_eye +14 -15
- data/examples/custom_check.eye +24 -0
- data/examples/custom_trigger.eye +30 -0
- data/examples/delayed_job.eye +3 -3
- data/examples/dependency.eye +10 -11
- data/examples/leye_example/Eyefile +10 -0
- data/examples/notify.eye +3 -4
- data/examples/plugin/main.eye +5 -5
- data/examples/plugin/plugin.rb +10 -2
- data/examples/process_thin.rb +8 -8
- data/examples/processes/em.rb +18 -12
- data/examples/processes/forking.rb +5 -5
- data/examples/processes/sample.rb +46 -44
- data/examples/puma.eye +9 -8
- data/examples/rbenv.eye +5 -5
- data/examples/sidekiq.eye +3 -3
- data/examples/stress_test.eye +4 -4
- data/examples/syslog.eye +1 -1
- data/examples/test.eye +1 -2
- data/examples/thin-farm.eye +7 -8
- data/examples/triggers.eye +13 -15
- data/examples/unicorn.eye +12 -13
- data/eye.gemspec +16 -14
- data/lib/eye.rb +2 -3
- data/lib/eye/application.rb +5 -6
- data/lib/eye/checker.rb +44 -25
- data/lib/eye/checker/children_count.rb +1 -1
- data/lib/eye/checker/file_ctime.rb +1 -1
- data/lib/eye/checker/http.rb +13 -15
- data/lib/eye/checker/nop.rb +1 -0
- data/lib/eye/checker/socket.rb +60 -63
- data/lib/eye/checker/ssl_socket.rb +5 -5
- data/lib/eye/child_process.rb +6 -4
- data/lib/eye/cli.rb +74 -46
- data/lib/eye/cli/commands.rb +4 -5
- data/lib/eye/cli/render.rb +61 -41
- data/lib/eye/cli/server.rb +19 -16
- data/lib/eye/client.rb +1 -0
- data/lib/eye/config.rb +36 -33
- data/lib/eye/controller.rb +2 -3
- data/lib/eye/controller/commands.rb +1 -1
- data/lib/eye/controller/helpers.rb +2 -2
- data/lib/eye/controller/load.rb +19 -17
- data/lib/eye/controller/options.rb +1 -5
- data/lib/eye/controller/send_command.rb +21 -23
- data/lib/eye/controller/status.rb +17 -14
- data/lib/eye/dsl.rb +6 -1
- data/lib/eye/dsl/application_opts.rb +4 -3
- data/lib/eye/dsl/chain.rb +2 -2
- data/lib/eye/dsl/child_process_opts.rb +3 -3
- data/lib/eye/dsl/config_opts.rb +7 -7
- data/lib/eye/dsl/group_opts.rb +3 -3
- data/lib/eye/dsl/helpers.rb +1 -1
- data/lib/eye/dsl/main.rb +4 -3
- data/lib/eye/dsl/opts.rb +31 -28
- data/lib/eye/dsl/process_opts.rb +13 -7
- data/lib/eye/dsl/pure_opts.rb +13 -9
- data/lib/eye/dsl/validation.rb +48 -35
- data/lib/eye/group.rb +23 -8
- data/lib/eye/group/chain.rb +6 -6
- data/lib/eye/loader.rb +3 -3
- data/lib/eye/local.rb +9 -4
- data/lib/eye/logger.rb +11 -4
- data/lib/eye/notify.rb +10 -6
- data/lib/eye/notify/jabber.rb +1 -1
- data/lib/eye/notify/mail.rb +2 -2
- data/lib/eye/notify/slack.rb +4 -3
- data/lib/eye/process.rb +2 -0
- data/lib/eye/process/children.rb +4 -4
- data/lib/eye/process/commands.rb +38 -39
- data/lib/eye/process/config.rb +22 -16
- data/lib/eye/process/controller.rb +5 -19
- data/lib/eye/process/data.rb +11 -9
- data/lib/eye/process/monitor.rb +86 -76
- data/lib/eye/process/notify.rb +10 -10
- data/lib/eye/process/scheduler.rb +36 -31
- data/lib/eye/process/states.rb +7 -5
- data/lib/eye/process/states_history.rb +9 -3
- data/lib/eye/process/system.rb +35 -20
- data/lib/eye/process/trigger.rb +1 -5
- data/lib/eye/process/watchers.rb +12 -9
- data/lib/eye/reason.rb +4 -1
- data/lib/eye/server.rb +3 -2
- data/lib/eye/system.rb +22 -15
- data/lib/eye/system_resources.rb +17 -8
- data/lib/eye/trigger.rb +18 -16
- data/lib/eye/trigger/check_dependency.rb +7 -4
- data/lib/eye/trigger/flapping.rb +24 -7
- data/lib/eye/trigger/starting_guard.rb +7 -6
- data/lib/eye/trigger/stop_children.rb +2 -2
- data/lib/eye/trigger/transition.rb +1 -1
- data/lib/eye/trigger/wait_dependency.rb +3 -2
- data/lib/eye/utils.rb +4 -3
- data/lib/eye/utils/alive_array.rb +9 -4
- data/lib/eye/utils/celluloid_chain.rb +12 -10
- data/lib/eye/utils/mini_active_support.rb +16 -16
- data/lib/eye/utils/pmap.rb +2 -0
- data/lib/eye/utils/tail.rb +2 -2
- metadata +39 -8
- data/lib/eye/utils/leak_19.rb +0 -10
data/examples/notify.eye
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Notify example
|
2
2
|
|
3
3
|
Eye.config do
|
4
|
-
mail :
|
4
|
+
mail host: 'mx.some.host', port: 25, domain: 'some.host'
|
5
5
|
contact :errors, :mail, 'error@some.host'
|
6
6
|
contact :dev, :mail, 'dev@some.host'
|
7
7
|
end
|
@@ -11,9 +11,8 @@ Eye.application :some do
|
|
11
11
|
|
12
12
|
process :some_process do
|
13
13
|
notify :dev, :info
|
14
|
-
pid_file
|
14
|
+
pid_file '1.pid'
|
15
15
|
|
16
|
-
|
16
|
+
# ...
|
17
17
|
end
|
18
|
-
|
19
18
|
end
|
data/examples/plugin/main.eye
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
Eye.load('./plugin.rb')
|
2
2
|
|
3
3
|
Eye.config do
|
4
|
-
logger
|
5
|
-
enable_reactor(1.second,
|
6
|
-
enable_saver(
|
4
|
+
logger '/tmp/eye.log'
|
5
|
+
enable_reactor(1.second, '/tmp/cmd.txt')
|
6
|
+
enable_saver('/tmp/saver.log')
|
7
7
|
end
|
8
8
|
|
9
9
|
Eye.app :app do
|
10
10
|
process :process do
|
11
|
-
pid_file
|
12
|
-
start_command
|
11
|
+
pid_file '/tmp/p.pid'
|
12
|
+
start_command 'sleep 10'
|
13
13
|
daemonize true
|
14
14
|
end
|
15
15
|
end
|
data/examples/plugin/plugin.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
class Reactor
|
2
|
+
|
2
3
|
include Celluloid
|
3
4
|
|
4
5
|
def initialize(interval, filename)
|
@@ -21,11 +22,13 @@ class Reactor
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def execute_command(cmd)
|
24
|
-
Eye::Control.command(cmd, 'all') if %w
|
25
|
+
Eye::Control.command(cmd, 'all') if %w[restart start stop].include?(cmd)
|
25
26
|
end
|
27
|
+
|
26
28
|
end
|
27
29
|
|
28
30
|
class Saver < Eye::Trigger::Custom
|
31
|
+
|
29
32
|
param :log_name, String, true
|
30
33
|
|
31
34
|
def check(trans)
|
@@ -35,6 +38,7 @@ class Saver < Eye::Trigger::Custom
|
|
35
38
|
def tlogger
|
36
39
|
@tlogger ||= Logger.new(log_name)
|
37
40
|
end
|
41
|
+
|
38
42
|
end
|
39
43
|
|
40
44
|
def reactor
|
@@ -43,21 +47,25 @@ end
|
|
43
47
|
|
44
48
|
# Extend config options, add enable_reactor
|
45
49
|
class Eye::Dsl::ConfigOpts
|
50
|
+
|
46
51
|
def enable_reactor(*args)
|
47
52
|
@config[:reactor] = args
|
48
53
|
end
|
49
54
|
|
50
55
|
def enable_saver(save_log)
|
51
56
|
Eye.application '__default__' do
|
52
|
-
trigger :saver, :
|
57
|
+
trigger :saver, log_name: save_log
|
53
58
|
end
|
54
59
|
end
|
60
|
+
|
55
61
|
end
|
56
62
|
|
57
63
|
# extend controller to execute method, and config loads
|
58
64
|
class Eye::Controller
|
65
|
+
|
59
66
|
def set_opt_reactor(args)
|
60
67
|
reactor.terminate if reactor
|
61
68
|
Celluloid::Actor[:reactor] = Reactor.supervise(*args)
|
62
69
|
end
|
70
|
+
|
63
71
|
end
|
data/examples/process_thin.rb
CHANGED
@@ -4,16 +4,16 @@ def thin(proxy, port)
|
|
4
4
|
name = "thin-#{port}"
|
5
5
|
|
6
6
|
opts = [
|
7
|
-
|
7
|
+
'-l thins.log',
|
8
8
|
"-p #{port}",
|
9
9
|
"-P #{name}.pid",
|
10
|
-
|
11
|
-
|
10
|
+
'-d',
|
11
|
+
'-R thin.ru',
|
12
12
|
"--tag #{proxy.app.name}.#{proxy.name}",
|
13
|
-
|
13
|
+
'-t 60',
|
14
14
|
"-e #{proxy.env['RAILS_ENV']}",
|
15
15
|
"-c #{proxy.working_dir}",
|
16
|
-
|
16
|
+
'-a 127.0.0.1'
|
17
17
|
]
|
18
18
|
|
19
19
|
proxy.process(name) do
|
@@ -22,9 +22,9 @@ def thin(proxy, port)
|
|
22
22
|
start_command "#{BUNDLE} exec thin start #{opts * ' '}"
|
23
23
|
stop_signals [:QUIT, 2.seconds, :TERM, 1.seconds, :KILL]
|
24
24
|
|
25
|
-
stdall
|
25
|
+
stdall 'thin.stdall.log'
|
26
26
|
|
27
|
-
check :http, :
|
28
|
-
:
|
27
|
+
check :http, url: "http://127.0.0.1:#{port}/hello", pattern: /World/,
|
28
|
+
every: 5.seconds, times: [2, 3], timeout: 1.second
|
29
29
|
end
|
30
30
|
end
|
data/examples/processes/em.rb
CHANGED
@@ -5,7 +5,9 @@ def answer(data)
|
|
5
5
|
case data
|
6
6
|
when 'ping' then "pong\n"
|
7
7
|
when 'bad' then "what\n"
|
8
|
-
when 'timeout' then
|
8
|
+
when 'timeout' then
|
9
|
+
sleep 5
|
10
|
+
"ok\n"
|
9
11
|
when 'exception' then raise 'haha'
|
10
12
|
when 'quit' then EM.stop
|
11
13
|
when 'big' then 'a' * 10_000_000
|
@@ -13,45 +15,49 @@ def answer(data)
|
|
13
15
|
end
|
14
16
|
|
15
17
|
class Echo < EM::Connection
|
18
|
+
|
16
19
|
def post_init
|
17
|
-
puts
|
20
|
+
puts '-- someone connected to the echo server!'
|
18
21
|
end
|
19
22
|
|
20
|
-
def receive_data
|
23
|
+
def receive_data(data)
|
21
24
|
puts "receive #{data.inspect} "
|
22
25
|
send_data(answer(data))
|
23
26
|
end
|
24
27
|
|
25
28
|
def unbind
|
26
|
-
|
29
|
+
puts '-- someone disconnected from the echo server!'
|
27
30
|
end
|
31
|
+
|
28
32
|
end
|
29
33
|
|
30
34
|
class EchoObj < EM::Connection
|
35
|
+
|
31
36
|
include EM::P::ObjectProtocol
|
32
37
|
|
33
38
|
def post_init
|
34
|
-
puts
|
39
|
+
puts '-- someone connected to the echo server!'
|
35
40
|
end
|
36
41
|
|
37
|
-
def receive_object
|
42
|
+
def receive_object(obj) # {:command => 'ping'}
|
38
43
|
puts "receive #{obj.inspect}"
|
39
44
|
send_object(answer(obj[:command]).chop)
|
40
45
|
end
|
41
46
|
|
42
47
|
def unbind
|
43
|
-
puts
|
48
|
+
puts '-- someone disconnected from the echo server!'
|
44
49
|
end
|
50
|
+
|
45
51
|
end
|
46
52
|
|
47
|
-
trap
|
48
|
-
puts
|
53
|
+
trap 'QUIT' do
|
54
|
+
puts 'quit signal, stopping'
|
49
55
|
EM.stop
|
50
56
|
end
|
51
57
|
|
52
58
|
EM.run do
|
53
|
-
EM.start_server '127.0.0.1',
|
54
|
-
EM.start_server '127.0.0.1',
|
55
|
-
EM.start_server
|
59
|
+
EM.start_server '127.0.0.1', 33_221, Echo
|
60
|
+
EM.start_server '127.0.0.1', 33_222, EchoObj
|
61
|
+
EM.start_server '/tmp/em_test_sock', nil, Echo
|
56
62
|
puts 'started'
|
57
63
|
end
|
@@ -4,13 +4,13 @@ require 'forking'
|
|
4
4
|
root = File.expand_path(File.dirname(__FILE__))
|
5
5
|
cnt = (ENV['FORKING_COUNT'] || 3).to_i
|
6
6
|
|
7
|
-
f = Forking.new(:
|
8
|
-
|
9
|
-
|
7
|
+
f = Forking.new(name: 'forking', working_dir: root,
|
8
|
+
log_file: "#{root}/forking.log",
|
9
|
+
pid_file: "#{root}/forking.pid", sync_log: true)
|
10
10
|
|
11
11
|
cnt.times do |i|
|
12
|
-
f.spawn(:
|
13
|
-
$0 =
|
12
|
+
f.spawn(log_file: "#{root}/child#{i}.log", sync_log: true) do
|
13
|
+
$0 = 'forking child'
|
14
14
|
t = 0
|
15
15
|
loop do
|
16
16
|
p "#{Time.now} - #{Time.now.to_f} - #{i} - tick"
|
@@ -9,49 +9,49 @@ options = {}
|
|
9
9
|
optparse = OptionParser.new do|opts|
|
10
10
|
# This displays the help screen, all programs are
|
11
11
|
# assumed to have this option.
|
12
|
-
opts.on(
|
12
|
+
opts.on('-h', '--help', 'Display this screen') do
|
13
13
|
puts opts
|
14
14
|
exit
|
15
15
|
end
|
16
16
|
|
17
|
-
opts.on(
|
17
|
+
opts.on('-p', '--pid FILE', 'pid_file') do |a|
|
18
18
|
options[:pid_file] = a
|
19
19
|
end
|
20
20
|
|
21
|
-
opts.on(
|
21
|
+
opts.on('-l', '--log FILE', 'log_file') do |a|
|
22
22
|
options[:log_file] = a
|
23
23
|
end
|
24
24
|
|
25
|
-
opts.on(
|
25
|
+
opts.on('-L', '--lock FILE', 'lock_file') do |a|
|
26
26
|
options[:lock_file] = a
|
27
27
|
end
|
28
28
|
|
29
|
-
opts.on(
|
29
|
+
opts.on('-d', '--daemonize', 'Daemonize') do
|
30
30
|
options[:daemonize] = true
|
31
31
|
end
|
32
32
|
|
33
|
-
opts.on(
|
33
|
+
opts.on('-s', '--daemonize_delay DELAY', 'Daemonized time') do |d|
|
34
34
|
options[:daemonize_delay] = d
|
35
35
|
end
|
36
36
|
|
37
|
-
opts.on(
|
37
|
+
opts.on('-r', '--raise', 'Raised execution') do
|
38
38
|
options[:raise] = true
|
39
39
|
end
|
40
40
|
|
41
|
-
opts.on(
|
41
|
+
opts.on('-w', '--watch_file FILE', 'Exit on touched file') do |w|
|
42
42
|
options[:watch_file] = w
|
43
43
|
end
|
44
44
|
|
45
|
-
opts.on(
|
45
|
+
opts.on('-W', '--watch_file_delay DELAY', 'Exit on touched file, after delay') do |w|
|
46
46
|
options[:watch_file_delay] = w
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
50
49
|
|
51
50
|
optparse.parse!
|
52
51
|
|
53
52
|
module Sample
|
54
|
-
|
53
|
+
|
54
|
+
def puts(mes = '')
|
55
55
|
tm = Time.now
|
56
56
|
STDOUT.puts "#{tm} (#{tm.to_f}) - #{mes}"
|
57
57
|
STDOUT.flush
|
@@ -63,15 +63,15 @@ module Sample
|
|
63
63
|
if daemonize_delay && daemonize_delay.to_f > 0
|
64
64
|
puts "daemonize delay start #{daemonize_delay}"
|
65
65
|
sleep daemonize_delay.to_f
|
66
|
-
puts
|
66
|
+
puts 'daemonize delay end'
|
67
67
|
end
|
68
68
|
|
69
69
|
daemon
|
70
|
-
STDOUT.reopen(log_file,
|
71
|
-
STDERR.reopen(log_file,
|
72
|
-
File.open(pid_file, 'w'){|f| f.write $$.to_s}
|
70
|
+
STDOUT.reopen(log_file, 'a')
|
71
|
+
STDERR.reopen(log_file, 'a')
|
72
|
+
File.open(pid_file, 'w') { |f| f.write $$.to_s }
|
73
73
|
|
74
|
-
puts
|
74
|
+
puts 'daemonized'
|
75
75
|
end
|
76
76
|
|
77
77
|
def daemon
|
@@ -79,11 +79,12 @@ module Sample
|
|
79
79
|
Process.setsid # Become session leader.
|
80
80
|
exit if fork # Zap session leader. See [1].
|
81
81
|
|
82
|
-
STDIN.reopen
|
83
|
-
STDOUT.reopen
|
82
|
+
STDIN.reopen '/dev/null' # Free file descriptors and
|
83
|
+
STDOUT.reopen '/dev/null', 'a' # point them somewhere sensible.
|
84
84
|
STDERR.reopen '/dev/null', 'a'
|
85
|
-
|
85
|
+
0
|
86
86
|
end
|
87
|
+
|
87
88
|
end
|
88
89
|
|
89
90
|
extend Sample
|
@@ -96,49 +97,50 @@ puts "Started #{ARGV.inspect}, #{options.inspect}, #{ENV['ENV1']}"
|
|
96
97
|
|
97
98
|
if options[:lock_file]
|
98
99
|
if File.exist?(options[:lock_file])
|
99
|
-
puts
|
100
|
+
puts 'Lock file exists, exiting'
|
100
101
|
exit 1
|
101
102
|
else
|
102
|
-
File.open(options[:lock_file], 'w'){|f| f.write $$ }
|
103
|
+
File.open(options[:lock_file], 'w') { |f| f.write $$ }
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
106
107
|
if options[:raise]
|
107
|
-
puts
|
108
|
+
puts 'Raised'
|
108
109
|
File.unlink(options[:lock_file]) if options[:lock_file]
|
109
110
|
exit 1
|
110
111
|
end
|
111
112
|
|
112
|
-
trap(
|
113
|
-
puts
|
113
|
+
trap('USR1') do
|
114
|
+
puts 'USR1 signal!'
|
114
115
|
end
|
115
116
|
|
116
|
-
trap(
|
117
|
-
puts
|
118
|
-
|
119
|
-
300_000.times{|i|
|
117
|
+
trap('USR2') do
|
118
|
+
puts 'USR2 start memory leak'
|
119
|
+
ar = []
|
120
|
+
300_000.times { |i| ar << "memory leak #{i}" * 10 }
|
120
121
|
end
|
121
122
|
|
122
|
-
|
123
|
-
|
124
|
-
puts "tick"
|
125
|
-
|
126
|
-
if options[:watch_file]
|
127
|
-
if File.exist?(options[:watch_file])
|
128
|
-
puts "watch file finded"
|
129
|
-
File.unlink(options[:watch_file])
|
123
|
+
def check_watch_file(options)
|
124
|
+
return unless options[:watch_file] && File.exist?(options[:watch_file])
|
130
125
|
|
131
|
-
|
132
|
-
|
133
|
-
sleep options[:watch_file_delay].to_f
|
134
|
-
puts "watch_file delay end"
|
135
|
-
end
|
126
|
+
puts 'watch file finded'
|
127
|
+
File.unlink(options[:watch_file])
|
136
128
|
|
137
|
-
|
138
|
-
|
129
|
+
if options[:watch_file_delay]
|
130
|
+
puts 'watch_file delay start'
|
131
|
+
sleep options[:watch_file_delay].to_f
|
132
|
+
puts 'watch_file delay end'
|
139
133
|
end
|
134
|
+
|
135
|
+
true
|
136
|
+
end
|
137
|
+
|
138
|
+
loop do
|
139
|
+
sleep 0.1
|
140
|
+
puts 'tick'
|
141
|
+
break if check_watch_file(options)
|
140
142
|
end
|
141
143
|
|
142
|
-
puts
|
144
|
+
puts 'exit'
|
143
145
|
File.unlink(options[:lock_file]) if options[:lock_file]
|
144
146
|
exit 0
|
data/examples/puma.eye
CHANGED
@@ -9,21 +9,22 @@ end
|
|
9
9
|
Eye.application :puma do
|
10
10
|
env 'RAILS_ENV' => RAILS_ENV
|
11
11
|
working_dir ROOT
|
12
|
-
trigger :flapping, :
|
12
|
+
trigger :flapping, times: 10, within: 1.minute
|
13
13
|
|
14
14
|
process :puma do
|
15
15
|
daemonize true
|
16
|
-
pid_file
|
17
|
-
stdall
|
16
|
+
pid_file 'puma.pid'
|
17
|
+
stdall 'puma.log'
|
18
18
|
|
19
19
|
start_command "#{BUNDLE} exec puma --port 33280 --environment #{RAILS_ENV} thin.ru"
|
20
20
|
stop_signals [:TERM, 5.seconds, :KILL]
|
21
|
-
restart_command
|
21
|
+
restart_command 'kill -USR2 {PID}'
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
# just sleep this until process get up status
|
24
|
+
# (maybe enought to puma soft restart)
|
25
|
+
restart_grace 10.seconds
|
25
26
|
|
26
|
-
check :cpu, :
|
27
|
-
check :memory, :
|
27
|
+
check :cpu, every: 30, below: 80, times: 3
|
28
|
+
check :memory, every: 30, below: 70.megabytes, times: [3, 5]
|
28
29
|
end
|
29
30
|
end
|
data/examples/rbenv.eye
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
Eye.application
|
1
|
+
Eye.application 'rbenv_example' do
|
2
2
|
env 'RBENV_ROOT' => '/usr/local/rbenv', 'PATH' => "/usr/local/rbenv/shims:/usr/local/rbenv/bin:#{ENV['PATH']}"
|
3
3
|
working_dir File.expand_path(File.join(File.dirname(__FILE__), %w[ processes ]))
|
4
4
|
|
5
|
-
process
|
6
|
-
pid_file
|
7
|
-
start_command
|
5
|
+
process 'some_process' do
|
6
|
+
pid_file 'some.pid'
|
7
|
+
start_command 'ruby some.rb'
|
8
8
|
daemonize true
|
9
|
-
stdall
|
9
|
+
stdall 'some.log'
|
10
10
|
end
|
11
11
|
end
|