eye 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +31 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +132 -0
- data/Rakefile +18 -0
- data/bin/eye +282 -0
- data/bin/loader_eye +56 -0
- data/examples/processes/em.rb +56 -0
- data/examples/processes/forking.rb +20 -0
- data/examples/processes/sample.rb +144 -0
- data/examples/rbenv.eye +11 -0
- data/examples/test.eye +65 -0
- data/examples/unicorn.eye +29 -0
- data/eye.gemspec +37 -0
- data/lib/eye.rb +25 -0
- data/lib/eye/application.rb +65 -0
- data/lib/eye/checker.rb +118 -0
- data/lib/eye/checker/cpu.rb +27 -0
- data/lib/eye/checker/file_ctime.rb +29 -0
- data/lib/eye/checker/file_size.rb +38 -0
- data/lib/eye/checker/http.rb +94 -0
- data/lib/eye/checker/memory.rb +27 -0
- data/lib/eye/checker/socket.rb +148 -0
- data/lib/eye/checker/validation.rb +49 -0
- data/lib/eye/child_process.rb +75 -0
- data/lib/eye/client.rb +32 -0
- data/lib/eye/control.rb +2 -0
- data/lib/eye/controller.rb +43 -0
- data/lib/eye/controller/commands.rb +64 -0
- data/lib/eye/controller/helpers.rb +61 -0
- data/lib/eye/controller/load.rb +224 -0
- data/lib/eye/controller/send_command.rb +88 -0
- data/lib/eye/controller/status.rb +136 -0
- data/lib/eye/dsl.rb +52 -0
- data/lib/eye/dsl/application_opts.rb +33 -0
- data/lib/eye/dsl/chain.rb +12 -0
- data/lib/eye/dsl/child_process_opts.rb +7 -0
- data/lib/eye/dsl/config_opts.rb +11 -0
- data/lib/eye/dsl/group_opts.rb +27 -0
- data/lib/eye/dsl/helpers.rb +12 -0
- data/lib/eye/dsl/main.rb +58 -0
- data/lib/eye/dsl/opts.rb +88 -0
- data/lib/eye/dsl/process_opts.rb +21 -0
- data/lib/eye/dsl/pure_opts.rb +132 -0
- data/lib/eye/dsl/validate.rb +41 -0
- data/lib/eye/group.rb +125 -0
- data/lib/eye/group/chain.rb +68 -0
- data/lib/eye/io/unix_server.rb +44 -0
- data/lib/eye/io/unix_socket.rb +39 -0
- data/lib/eye/loader.rb +13 -0
- data/lib/eye/logger.rb +80 -0
- data/lib/eye/process.rb +83 -0
- data/lib/eye/process/child.rb +61 -0
- data/lib/eye/process/commands.rb +256 -0
- data/lib/eye/process/config.rb +70 -0
- data/lib/eye/process/controller.rb +72 -0
- data/lib/eye/process/data.rb +46 -0
- data/lib/eye/process/monitor.rb +97 -0
- data/lib/eye/process/notify.rb +17 -0
- data/lib/eye/process/scheduler.rb +50 -0
- data/lib/eye/process/states.rb +92 -0
- data/lib/eye/process/states_history.rb +62 -0
- data/lib/eye/process/system.rb +60 -0
- data/lib/eye/process/trigger.rb +32 -0
- data/lib/eye/process/watchers.rb +67 -0
- data/lib/eye/server.rb +51 -0
- data/lib/eye/settings.rb +35 -0
- data/lib/eye/system.rb +145 -0
- data/lib/eye/system_resources.rb +83 -0
- data/lib/eye/trigger.rb +53 -0
- data/lib/eye/trigger/flapping.rb +24 -0
- data/lib/eye/utils.rb +5 -0
- data/lib/eye/utils/alive_array.rb +31 -0
- data/lib/eye/utils/celluloid_chain.rb +51 -0
- data/lib/eye/utils/leak_19.rb +7 -0
- data/lib/eye/utils/tail.rb +20 -0
- data/spec/checker/cpu_spec.rb +58 -0
- data/spec/checker/file_ctime_spec.rb +34 -0
- data/spec/checker/file_size_spec.rb +107 -0
- data/spec/checker/http_spec.rb +109 -0
- data/spec/checker/memory_spec.rb +64 -0
- data/spec/checker/socket_spec.rb +116 -0
- data/spec/checker_spec.rb +188 -0
- data/spec/child_process/child_process_spec.rb +46 -0
- data/spec/client_server_spec.rb +34 -0
- data/spec/controller/commands_spec.rb +92 -0
- data/spec/controller/controller_spec.rb +133 -0
- data/spec/controller/find_objects_spec.rb +150 -0
- data/spec/controller/group_spec.rb +110 -0
- data/spec/controller/intergration_spec.rb +327 -0
- data/spec/controller/load_spec.rb +326 -0
- data/spec/controller/races_spec.rb +70 -0
- data/spec/controller/stop_on_delete_spec.rb +157 -0
- data/spec/dsl/chain_spec.rb +140 -0
- data/spec/dsl/checks_spec.rb +202 -0
- data/spec/dsl/config_spec.rb +44 -0
- data/spec/dsl/dsl_spec.rb +73 -0
- data/spec/dsl/getter_spec.rb +223 -0
- data/spec/dsl/integration_spec.rb +311 -0
- data/spec/dsl/load_spec.rb +52 -0
- data/spec/dsl/process_spec.rb +330 -0
- data/spec/dsl/sub_procs_spec.rb +93 -0
- data/spec/dsl/with_server_spec.rb +104 -0
- data/spec/example/em.rb +57 -0
- data/spec/example/forking.rb +20 -0
- data/spec/example/sample.rb +154 -0
- data/spec/fixtures/dsl/0.rb +8 -0
- data/spec/fixtures/dsl/0a.rb +8 -0
- data/spec/fixtures/dsl/0c.rb +8 -0
- data/spec/fixtures/dsl/1.rb +5 -0
- data/spec/fixtures/dsl/bad.eye +6 -0
- data/spec/fixtures/dsl/configs/1.eye +3 -0
- data/spec/fixtures/dsl/configs/2.eye +1 -0
- data/spec/fixtures/dsl/configs/3.eye +1 -0
- data/spec/fixtures/dsl/configs/4.eye +3 -0
- data/spec/fixtures/dsl/empty.eye +20 -0
- data/spec/fixtures/dsl/include_test.eye +5 -0
- data/spec/fixtures/dsl/include_test/1.rb +6 -0
- data/spec/fixtures/dsl/include_test/ha.rb +4 -0
- data/spec/fixtures/dsl/include_test2.eye +5 -0
- data/spec/fixtures/dsl/integration.eye +30 -0
- data/spec/fixtures/dsl/integration2.eye +32 -0
- data/spec/fixtures/dsl/integration_locks.eye +30 -0
- data/spec/fixtures/dsl/integration_sor.eye +32 -0
- data/spec/fixtures/dsl/integration_sor2.eye +27 -0
- data/spec/fixtures/dsl/integration_sor3.eye +32 -0
- data/spec/fixtures/dsl/load.eye +25 -0
- data/spec/fixtures/dsl/load2.eye +7 -0
- data/spec/fixtures/dsl/load2_dup2.eye +13 -0
- data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
- data/spec/fixtures/dsl/load3.eye +10 -0
- data/spec/fixtures/dsl/load4.eye +7 -0
- data/spec/fixtures/dsl/load5.eye +8 -0
- data/spec/fixtures/dsl/load6.eye +17 -0
- data/spec/fixtures/dsl/load_dubls.eye +36 -0
- data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
- data/spec/fixtures/dsl/load_error.eye +5 -0
- data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_int.eye +8 -0
- data/spec/fixtures/dsl/load_int2.eye +13 -0
- data/spec/fixtures/dsl/load_logger.eye +26 -0
- data/spec/fixtures/dsl/load_logger2.eye +3 -0
- data/spec/fixtures/dsl/long_load.eye +5 -0
- data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
- data/spec/fixtures/dsl/subfolder2.eye +9 -0
- data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
- data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
- data/spec/fixtures/dsl/subfolder3.eye +8 -0
- data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
- data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
- data/spec/fixtures/dsl/subfolder4.eye +6 -0
- data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
- data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
- data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
- data/spec/mock_spec.rb +32 -0
- data/spec/process/checks/child_checks_spec.rb +79 -0
- data/spec/process/checks/cpu_spec.rb +114 -0
- data/spec/process/checks/ctime_spec.rb +43 -0
- data/spec/process/checks/fsize_spec.rb +22 -0
- data/spec/process/checks/http_spec.rb +52 -0
- data/spec/process/checks/intergration_spec.rb +32 -0
- data/spec/process/checks/memory_spec.rb +113 -0
- data/spec/process/child_process_spec.rb +125 -0
- data/spec/process/config_spec.rb +75 -0
- data/spec/process/controller_spec.rb +173 -0
- data/spec/process/monitoring_spec.rb +180 -0
- data/spec/process/restart_spec.rb +174 -0
- data/spec/process/scheduler_spec.rb +150 -0
- data/spec/process/start_spec.rb +261 -0
- data/spec/process/states_history_spec.rb +118 -0
- data/spec/process/stop_spec.rb +150 -0
- data/spec/process/system_spec.rb +100 -0
- data/spec/process/triggers/flapping_spec.rb +81 -0
- data/spec/process/update_config_spec.rb +63 -0
- data/spec/spec_helper.rb +120 -0
- data/spec/support/rr_celluloid.rb +36 -0
- data/spec/support/scheduler_hack.rb +16 -0
- data/spec/support/spec_support.rb +164 -0
- data/spec/system_resources_spec.rb +59 -0
- data/spec/system_spec.rb +170 -0
- data/spec/utils/alive_array_spec.rb +50 -0
- data/spec/utils/celluloid_chain_spec.rb +82 -0
- data/spec/utils/tail_spec.rb +21 -0
- metadata +558 -0
data/lib/eye/dsl/opts.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
2
|
+
|
3
|
+
STR_OPTIONS = [ :pid_file, :working_dir, :stdout, :stderr, :stdall, :start_command,
|
4
|
+
:stop_command, :restart_command ]
|
5
|
+
|
6
|
+
create_options_methods(STR_OPTIONS, String)
|
7
|
+
|
8
|
+
BOOL_OPTIONS = [ :daemonize, :keep_alive, :control_pid, :auto_start, :stop_on_delete]
|
9
|
+
|
10
|
+
create_options_methods(BOOL_OPTIONS, [TrueClass, FalseClass])
|
11
|
+
|
12
|
+
INTERVAL_OPTIONS = [ :check_alive_period, :start_timeout, :restart_timeout, :stop_timeout, :start_grace,
|
13
|
+
:restart_grace, :stop_grace, :childs_update_period ]
|
14
|
+
|
15
|
+
create_options_methods(INTERVAL_OPTIONS, [Fixnum, Float])
|
16
|
+
|
17
|
+
OTHER_OPTIONS = [ :environment, :stop_signals ]
|
18
|
+
|
19
|
+
create_options_methods(OTHER_OPTIONS)
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
def initialize(name = nil, parent = nil)
|
24
|
+
super(name, parent)
|
25
|
+
|
26
|
+
# ensure delete subobjects which can appears from parent config
|
27
|
+
@config.delete :groups
|
28
|
+
@config.delete :processes
|
29
|
+
|
30
|
+
@config[:application] = parent.name if parent.is_a?(Eye::Dsl::ApplicationOpts)
|
31
|
+
@config[:group] = parent.name if parent.is_a?(Eye::Dsl::GroupOpts)
|
32
|
+
|
33
|
+
# hack for full name
|
34
|
+
@full_name = parent.full_name if @name == '__default__'
|
35
|
+
end
|
36
|
+
|
37
|
+
def checks(type, opts = {})
|
38
|
+
type = type.to_sym
|
39
|
+
raise Eye::Dsl::Error, "unknown checker type #{type}" unless Eye::Checker::TYPES[type]
|
40
|
+
|
41
|
+
opts.merge!(:type => type)
|
42
|
+
Eye::Checker.validate!(opts)
|
43
|
+
|
44
|
+
@config[:checks] ||= {}
|
45
|
+
@config[:checks][type] = opts
|
46
|
+
end
|
47
|
+
|
48
|
+
def triggers(type, opts = {})
|
49
|
+
type = type.to_sym
|
50
|
+
raise Eye::Dsl::Error, "unknown trigger type #{type}" unless Eye::Trigger::TYPES[type]
|
51
|
+
|
52
|
+
opts.merge!(:type => type)
|
53
|
+
Eye::Trigger.validate!(opts)
|
54
|
+
|
55
|
+
@config[:triggers] ||= {}
|
56
|
+
@config[:triggers][type] = opts
|
57
|
+
end
|
58
|
+
|
59
|
+
# clear checks from parent
|
60
|
+
def nochecks(type)
|
61
|
+
type = type.to_sym
|
62
|
+
raise Eye::Dsl::Error, "unknown checker type #{type}" unless Eye::Checker::TYPES[type]
|
63
|
+
@config[:checks].try :delete, type
|
64
|
+
end
|
65
|
+
|
66
|
+
# clear triggers from parent
|
67
|
+
def notriggers(type)
|
68
|
+
type = type.to_sym
|
69
|
+
raise Eye::Dsl::Error, "unknown trigger type #{type}" unless Eye::Trigger::TYPES[type]
|
70
|
+
@config[:triggers].try :delete, type
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_environment(value)
|
74
|
+
raise Eye::Dsl::Error, "environment should be a hash, but not #{value.inspect}" unless value.is_a?(Hash)
|
75
|
+
@config[:environment] ||= {}
|
76
|
+
@config[:environment].merge!(value)
|
77
|
+
end
|
78
|
+
|
79
|
+
alias :env :environment
|
80
|
+
|
81
|
+
def set_stdall(value)
|
82
|
+
super
|
83
|
+
|
84
|
+
set_stdout value
|
85
|
+
set_stderr value
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Eye::Dsl::ProcessOpts < Eye::Dsl::Opts
|
2
|
+
|
3
|
+
def monitor_children(&block)
|
4
|
+
opts = Eye::Dsl::ChildProcessOpts.new
|
5
|
+
opts.instance_eval(&block)
|
6
|
+
@config[:monitor_children] ||= {}
|
7
|
+
@config[:monitor_children].merge!(opts.config)
|
8
|
+
end
|
9
|
+
|
10
|
+
def xmonitor_children(&block); end
|
11
|
+
|
12
|
+
def application
|
13
|
+
parent.try(:parent)
|
14
|
+
end
|
15
|
+
alias :app :application
|
16
|
+
|
17
|
+
def group
|
18
|
+
parent
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
class Eye::Dsl::PureOpts
|
2
|
+
|
3
|
+
def self.create_options_methods(arr, types = nil)
|
4
|
+
m = Module.new do
|
5
|
+
arr.each do |opt|
|
6
|
+
define_method("set_#{opt}") do |arg|
|
7
|
+
key = opt.to_sym
|
8
|
+
|
9
|
+
if (disallow_options && disallow_options.include?(key)) || (allow_options && !allow_options.include?(key))
|
10
|
+
raise Eye::Dsl::Error, "disallow option #{key} for #{self.class.inspect}"
|
11
|
+
end
|
12
|
+
|
13
|
+
if types
|
14
|
+
good_type = Array(types).any?{|type| arg.is_a?(type) } || arg.nil?
|
15
|
+
raise Eye::Dsl::Error, "bad :#{opt} value #{arg.inspect}, type should be #{types.inspect}" unless good_type
|
16
|
+
end
|
17
|
+
|
18
|
+
@config[key] = arg
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method("get_#{opt}") do
|
22
|
+
@config[ opt.to_sym ]
|
23
|
+
end
|
24
|
+
|
25
|
+
define_method(opt) do |*args|
|
26
|
+
if args.blank?
|
27
|
+
# getter
|
28
|
+
send "get_#{opt}"
|
29
|
+
else
|
30
|
+
send "set_#{opt}", *args
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method("#{opt}=") do |arg|
|
35
|
+
send opt, arg
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
self.send :include, m
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :name, :full_name
|
44
|
+
attr_reader :config, :parent
|
45
|
+
|
46
|
+
def initialize(name = nil, parent = nil)
|
47
|
+
@name = name.to_s
|
48
|
+
@full_name = @name
|
49
|
+
|
50
|
+
if parent
|
51
|
+
@parent = parent
|
52
|
+
@config = Marshal.load(Marshal.dump(parent.config)) # O_o ruby recommended deep clone
|
53
|
+
@full_name = "#{parent.full_name}:#{@full_name}"
|
54
|
+
else
|
55
|
+
@config = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
@config[:name] = @name if @name.present?
|
59
|
+
end
|
60
|
+
|
61
|
+
def allow_options
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def disallow_options
|
66
|
+
[]
|
67
|
+
end
|
68
|
+
|
69
|
+
# execute part of config on particular server
|
70
|
+
# array of strings
|
71
|
+
# regexp
|
72
|
+
# string
|
73
|
+
def with_server(glob = nil, &block)
|
74
|
+
on_server = true
|
75
|
+
|
76
|
+
if glob.present?
|
77
|
+
host = Eye::System.host
|
78
|
+
|
79
|
+
if glob.is_a?(Array)
|
80
|
+
on_server = !!glob.any?{|elem| elem == host}
|
81
|
+
elsif glob.is_a?(Regexp)
|
82
|
+
on_server = !!host.match(glob)
|
83
|
+
elsif glob.is_a?(String) || glob.is_a?(Symbol)
|
84
|
+
on_server = (host == glob.to_s)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
with_condition(on_server, &block)
|
89
|
+
|
90
|
+
on_server
|
91
|
+
end
|
92
|
+
|
93
|
+
def with_condition(cond = true, &block)
|
94
|
+
self.instance_eval(&block) if cond && block
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.with_parsed_file(file_name)
|
98
|
+
saved_parsed_filename = Eye.parsed_filename
|
99
|
+
|
100
|
+
require 'pathname'
|
101
|
+
|
102
|
+
real_filename = Eye.parsed_filename && File.symlink?(Eye.parsed_filename) ? File.readlink(Eye.parsed_filename) : Eye.parsed_filename
|
103
|
+
dirname = File.dirname(real_filename) rescue nil
|
104
|
+
path = Pathname.new(file_name).expand_path(dirname).to_s
|
105
|
+
|
106
|
+
Eye.parsed_filename = path
|
107
|
+
yield path
|
108
|
+
ensure
|
109
|
+
Eye.parsed_filename = saved_parsed_filename
|
110
|
+
end
|
111
|
+
|
112
|
+
def include(proc, *args)
|
113
|
+
if proc.is_a?(String)
|
114
|
+
self.class.with_parsed_file(proc) do |path|
|
115
|
+
if File.exists?(path)
|
116
|
+
Eye::Dsl.debug "=> load #{path}"
|
117
|
+
self.instance_eval(File.read(path))
|
118
|
+
Eye::Dsl.debug "<= load #{path}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
else
|
122
|
+
ie = if args.present?
|
123
|
+
lambda{|i| proc[i, *args] }
|
124
|
+
else
|
125
|
+
proc
|
126
|
+
end
|
127
|
+
|
128
|
+
self.instance_eval(&ie)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Eye::Dsl::Validate
|
2
|
+
|
3
|
+
# validate global config rules
|
4
|
+
def validate(config)
|
5
|
+
cfg = config[:config]
|
6
|
+
config = config[:applications]
|
7
|
+
|
8
|
+
all_processes = config.values.map{|e| (e[:groups] || {}).values.map{|c| (c[:processes] || {}).values} }.flatten
|
9
|
+
|
10
|
+
# Check blank pid_files
|
11
|
+
|
12
|
+
no_pid_file = all_processes.select{|c| c[:pid_file].blank? }
|
13
|
+
if no_pid_file.present?
|
14
|
+
raise Eye::Dsl::Error, "blank pid_file for: #{no_pid_file.map{|c| c[:name]} * ', '}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Check dublicates of the full pid_file
|
18
|
+
|
19
|
+
dubl_pids = all_processes.each_with_object(Hash.new(0)) do |o, h|
|
20
|
+
ex_pid_file = Eye::System.normalized_file(o[:pid_file], o[:working_dir])
|
21
|
+
h[ex_pid_file] += 1
|
22
|
+
end
|
23
|
+
dubl_pids = dubl_pids.select{|k,v| v>1}
|
24
|
+
|
25
|
+
if dubl_pids.present?
|
26
|
+
raise Eye::Dsl::Error, "dublicate pid_files: #{dubl_pids.inspect}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Check dublicates of the full_name
|
30
|
+
dubl_names = all_processes.each_with_object(Hash.new(0)) do |o, h|
|
31
|
+
full_name = "#{o[:application]}:#{o[:group]}:#{o[:name]}"
|
32
|
+
h[full_name] += 1
|
33
|
+
end
|
34
|
+
dubl_names = dubl_names.select{|k,v| v>1}
|
35
|
+
|
36
|
+
if dubl_names.present?
|
37
|
+
raise Eye::Dsl::Error, "dublicate names: #{dubl_names.inspect}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/eye/group.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'celluloid'
|
2
|
+
|
3
|
+
class Eye::Group
|
4
|
+
include Celluloid
|
5
|
+
|
6
|
+
autoload :Chain, 'eye/group/chain'
|
7
|
+
|
8
|
+
include Eye::Logger::Helpers
|
9
|
+
include Eye::Process::Scheduler
|
10
|
+
include Eye::Group::Chain
|
11
|
+
|
12
|
+
attr_reader :processes, :name, :hidden, :config
|
13
|
+
|
14
|
+
def initialize(name, config)
|
15
|
+
@name = name
|
16
|
+
@config = config
|
17
|
+
@logger = Eye::Logger.new(full_name)
|
18
|
+
@processes = Eye::Utils::AliveArray.new
|
19
|
+
@hidden = (name == '__default__')
|
20
|
+
debug 'created'
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_name
|
24
|
+
@full_name ||= "#{@config[:application]}:#{@name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_config(cfg)
|
28
|
+
@config = cfg
|
29
|
+
@full_name = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_process(process)
|
33
|
+
@processes << process
|
34
|
+
end
|
35
|
+
|
36
|
+
# sort processes in name order
|
37
|
+
def resort_processes
|
38
|
+
@processes = @processes.sort_by(&:name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def status_data(debug = false)
|
42
|
+
plist = @processes.map{|p| p.status_data(debug) }
|
43
|
+
|
44
|
+
h = { name: name, type: :group, subtree: plist }
|
45
|
+
|
46
|
+
h.merge!(debug: debug_data) if debug
|
47
|
+
|
48
|
+
# show current chain
|
49
|
+
if current_scheduled_command
|
50
|
+
h.update(current_command: current_scheduled_command)
|
51
|
+
|
52
|
+
if (chain_commands = scheduler_actions_list) && chain_commands.present?
|
53
|
+
h.update(chain_commands: chain_commands)
|
54
|
+
end
|
55
|
+
|
56
|
+
if @chain_processes_current && @chain_processes_count
|
57
|
+
h.update(chain_progress: [@chain_processes_current, @chain_processes_count])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
h
|
62
|
+
end
|
63
|
+
|
64
|
+
def debug_data
|
65
|
+
{:queue => scheduler_actions_list, :chain => chain_status}
|
66
|
+
end
|
67
|
+
|
68
|
+
def send_command(command, *args)
|
69
|
+
info "send_command: #{command}"
|
70
|
+
|
71
|
+
if command == :delete
|
72
|
+
delete *args
|
73
|
+
else
|
74
|
+
schedule command, *args, "#{command} by user"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def start
|
79
|
+
chain_command :start
|
80
|
+
end
|
81
|
+
|
82
|
+
def stop
|
83
|
+
async_schedule :stop
|
84
|
+
end
|
85
|
+
|
86
|
+
def restart
|
87
|
+
chain_command :restart
|
88
|
+
end
|
89
|
+
|
90
|
+
def delete
|
91
|
+
async_schedule :delete
|
92
|
+
terminate
|
93
|
+
end
|
94
|
+
|
95
|
+
def monitor
|
96
|
+
chain_command :monitor
|
97
|
+
end
|
98
|
+
|
99
|
+
def unmonitor
|
100
|
+
async_schedule :unmonitor
|
101
|
+
end
|
102
|
+
|
103
|
+
def signal(sig)
|
104
|
+
async_schedule :signal, sig
|
105
|
+
end
|
106
|
+
|
107
|
+
def clear
|
108
|
+
@processes.clear
|
109
|
+
end
|
110
|
+
|
111
|
+
def sub_object?(obj)
|
112
|
+
@processes.include?(obj)
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def async_schedule(command, *args)
|
118
|
+
info "send to all processes #{command} #{args.present? ? args*',' : nil}"
|
119
|
+
|
120
|
+
@processes.each do |process|
|
121
|
+
process.send_command(command, *args)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Eye::Group::Chain
|
2
|
+
|
3
|
+
private
|
4
|
+
|
5
|
+
def chain_schedule(type, grace, command, *args)
|
6
|
+
info "start #{type} with #{grace}s chain #{command} #{args}"
|
7
|
+
|
8
|
+
@chain_processes_count = @processes.size
|
9
|
+
@chain_processes_current = 0
|
10
|
+
|
11
|
+
@processes.each do | process |
|
12
|
+
chain_schedule_process(process, type, command, *args)
|
13
|
+
|
14
|
+
@chain_processes_current = @chain_processes_current.to_i + 1
|
15
|
+
|
16
|
+
# to skip last sleep
|
17
|
+
break if @chain_processes_current.to_i == @chain_processes_count.to_i
|
18
|
+
|
19
|
+
# wait next process
|
20
|
+
sleep grace.to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
@chain_processes_count = nil
|
24
|
+
@chain_processes_current = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def chain_schedule_process(process, type, command, *args)
|
28
|
+
if type == :sync
|
29
|
+
# sync command, with waiting
|
30
|
+
process.send(command, *args)
|
31
|
+
else
|
32
|
+
# async command
|
33
|
+
process.send_command(command, *args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def chain_status
|
38
|
+
if @config[:chain]
|
39
|
+
[:start, :restart].map{|c| @config[:chain][c].try(:[], :grace) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def chain_command(command, *args)
|
44
|
+
chain_opts = chain_options(command)
|
45
|
+
chain_schedule(chain_opts[:type], chain_opts[:grace], command, *args)
|
46
|
+
end
|
47
|
+
|
48
|
+
# with such delay will chained processes by default
|
49
|
+
DEFAULT_CHAIN = 0.2
|
50
|
+
|
51
|
+
def chain_options(command)
|
52
|
+
command = :start if command == :monitor # hack for monitor command, work as start
|
53
|
+
|
54
|
+
if @config[:chain] && @config[:chain][command]
|
55
|
+
type = @config[:chain][command].try :[], :type
|
56
|
+
type = [:async, :sync].include?(type) ? type : :async
|
57
|
+
|
58
|
+
grace = @config[:chain][command].try :[], :grace
|
59
|
+
grace = grace ? (grace.to_f rescue DEFAULT_CHAIN) : DEFAULT_CHAIN
|
60
|
+
|
61
|
+
{:type => type, :grace => grace}
|
62
|
+
else
|
63
|
+
# default chain case
|
64
|
+
{:type => :async, :grace => DEFAULT_CHAIN}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|