eye 0.1.11 → 0.2
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.
- data/.rspec +1 -0
- data/Gemfile +2 -2
- data/README.md +41 -18
- data/bin/eye +4 -3
- data/examples/processes/em.rb +2 -1
- data/examples/processes/thin.ru +12 -0
- data/examples/sidekiq.eye +19 -0
- data/examples/test.eye +25 -16
- data/eye.gemspec +5 -3
- data/lib/eye.rb +2 -1
- data/lib/eye/checker/validation.rb +1 -1
- data/lib/eye/child_process.rb +27 -5
- data/lib/eye/controller/load.rb +13 -11
- data/lib/eye/controller/send_command.rb +32 -7
- data/lib/eye/controller/status.rb +4 -3
- data/lib/eye/dsl/config_opts.rb +38 -1
- data/lib/eye/dsl/opts.rb +12 -5
- data/lib/eye/dsl/pure_opts.rb +2 -2
- data/lib/eye/dsl/validate.rb +5 -0
- data/lib/eye/group.rb +1 -1
- data/lib/eye/group/chain.rb +2 -0
- data/lib/eye/notify.rb +86 -0
- data/lib/eye/notify/jabber.rb +30 -0
- data/lib/eye/notify/mail.rb +44 -0
- data/lib/eye/process.rb +5 -1
- data/lib/eye/process/child.rb +7 -8
- data/lib/eye/process/commands.rb +21 -18
- data/lib/eye/process/notify.rb +22 -7
- data/lib/eye/process/system.rb +18 -5
- data/lib/eye/process/validate.rb +23 -0
- data/lib/eye/system.rb +4 -1
- data/lib/eye/utils.rb +9 -0
- data/spec/checker_spec.rb +0 -1
- data/spec/client_server_spec.rb +0 -1
- data/spec/controller/controller_spec.rb +1 -1
- data/spec/controller/intergration_spec.rb +15 -0
- data/spec/controller/load_spec.rb +49 -4
- data/spec/dsl/chain_spec.rb +20 -14
- data/spec/dsl/checks_spec.rb +17 -0
- data/spec/dsl/notify_spec.rb +105 -0
- data/spec/dsl/process_spec.rb +50 -0
- data/spec/mock_spec.rb +0 -1
- data/spec/notify/jabber_spec.rb +25 -0
- data/spec/notify/mail_spec.rb +26 -0
- data/spec/notify_spec.rb +90 -0
- data/spec/process/config_spec.rb +0 -1
- data/spec/process/notify_spec.rb +27 -0
- data/spec/process/states_history_spec.rb +0 -1
- data/spec/process/stop_spec.rb +6 -0
- data/spec/process/system_spec.rb +34 -21
- data/spec/process/update_config_spec.rb +0 -1
- data/spec/spec_helper.rb +9 -2
- data/spec/support/spec_support.rb +0 -1
- data/spec/system_resources_spec.rb +0 -1
- data/spec/system_spec.rb +3 -6
- data/spec/utils/alive_array_spec.rb +0 -1
- data/spec/utils/celluloid_chain_spec.rb +0 -1
- data/spec/utils/tail_spec.rb +0 -1
- metadata +71 -7
|
@@ -2,13 +2,12 @@ module Eye::Controller::SendCommand
|
|
|
2
2
|
|
|
3
3
|
def send_command(command, *obj_strs)
|
|
4
4
|
matched_objects(*obj_strs) do |obj|
|
|
5
|
-
obj.send_command(command)
|
|
6
|
-
|
|
7
5
|
if command.to_sym == :delete
|
|
8
6
|
remove_object_from_tree(obj)
|
|
9
7
|
set_proc_line # to sync proc line if was delete application
|
|
10
|
-
GC.start
|
|
11
8
|
end
|
|
9
|
+
|
|
10
|
+
obj.send_command(command)
|
|
12
11
|
end
|
|
13
12
|
end
|
|
14
13
|
|
|
@@ -32,9 +31,29 @@ private
|
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
def remove_object_from_tree(obj)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
klass = obj.class
|
|
35
|
+
|
|
36
|
+
if klass == Eye::Application
|
|
37
|
+
@applications.delete(obj)
|
|
38
|
+
@current_config[:applications].delete(obj.name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if klass == Eye::Group
|
|
42
|
+
@applications.each{|app| app.groups.delete(obj) }
|
|
43
|
+
@current_config[:applications].each do |app_name, app_cfg|
|
|
44
|
+
app_cfg[:groups].delete(obj.name)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if klass == Eye::Process
|
|
49
|
+
@applications.each{|app| app.groups.each{|gr| gr.processes.delete(obj) }}
|
|
50
|
+
|
|
51
|
+
@current_config[:applications].each do |app_name, app_cfg|
|
|
52
|
+
app_cfg[:groups].each do |gr_name, gr_cfg|
|
|
53
|
+
gr_cfg[:processes].delete(obj.name)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
38
57
|
end
|
|
39
58
|
|
|
40
59
|
# find object to action, restart ... (app, group or process)
|
|
@@ -78,7 +97,13 @@ private
|
|
|
78
97
|
# find process
|
|
79
98
|
@applications.each do |a|
|
|
80
99
|
a.groups.each do |gr|
|
|
81
|
-
|
|
100
|
+
gr.processes.each do |p|
|
|
101
|
+
res << p if p.name =~ r || p.full_name =~ r
|
|
102
|
+
|
|
103
|
+
if p.childs.present?
|
|
104
|
+
res += p.childs.values.select{|ch| ch.name =~ r || ch.full_name =~ r }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
82
107
|
end
|
|
83
108
|
end
|
|
84
109
|
|
|
@@ -23,7 +23,7 @@ module Eye::Controller::Status
|
|
|
23
23
|
make_str({:subtree => @applications.map{|a| a.status_data_short } }).to_s
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def info_string_debug(show_config = false)
|
|
26
|
+
def info_string_debug(show_config = false, show_processes = false)
|
|
27
27
|
actors = Celluloid::Actor.all.map{|actor| actor.instance_variable_get(:@klass) }.group_by{|a| a}.map{|k,v| [k, v.size]}.sort_by{|a|a[1]}.reverse
|
|
28
28
|
|
|
29
29
|
str = <<-S
|
|
@@ -34,10 +34,11 @@ Socket: #{Eye::Settings::socket_path}
|
|
|
34
34
|
PidPath: #{Eye::Settings::pid_path}
|
|
35
35
|
Actors: #{actors.inspect}
|
|
36
36
|
|
|
37
|
-
#{make_str(info_data_debug)}
|
|
38
37
|
S
|
|
39
38
|
|
|
40
|
-
if
|
|
39
|
+
str += make_str(info_data_debug) + "\n" if show_processes.present?
|
|
40
|
+
|
|
41
|
+
if show_config.present?
|
|
41
42
|
str += "\nCurrent config: \n"
|
|
42
43
|
str += YAML.dump(current_config)
|
|
43
44
|
end
|
data/lib/eye/dsl/config_opts.rb
CHANGED
|
@@ -3,9 +3,46 @@ class Eye::Dsl::ConfigOpts < Eye::Dsl::PureOpts
|
|
|
3
3
|
create_options_methods([:logger], String)
|
|
4
4
|
create_options_methods([:logger_level], Fixnum)
|
|
5
5
|
create_options_methods([:http], Hash)
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
def set_logger(logger)
|
|
8
8
|
logger.blank? ? super('') : super
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
# ==== contact options ==============================
|
|
12
|
+
|
|
13
|
+
Eye::Notify::TYPES.keys.each do |not_system|
|
|
14
|
+
create_options_methods([not_system], Hash)
|
|
15
|
+
|
|
16
|
+
define_method("set_#{not_system}") do |value|
|
|
17
|
+
value = value.merge(:type => not_system)
|
|
18
|
+
super(value)
|
|
19
|
+
Eye::Notify.validate!(value)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def contact(contact_name, contact_type, contact, contact_opts = {})
|
|
24
|
+
raise Eye::Dsl::Error, "unknown contact_type #{contact_type}" unless Eye::Notify::TYPES[contact_type]
|
|
25
|
+
raise Eye::Dsl::Error, "contact should be a String" unless contact.is_a?(String)
|
|
26
|
+
|
|
27
|
+
notify_hash = @config[contact_type] || (@parent && @parent.config[contact_type]) || Eye::parsed_config[:config][contact_type] || {}
|
|
28
|
+
validate_hash = notify_hash.merge(contact_opts).merge(:type => contact_type)
|
|
29
|
+
|
|
30
|
+
Eye::Notify.validate!(validate_hash)
|
|
31
|
+
|
|
32
|
+
@config[:contacts] ||= {}
|
|
33
|
+
@config[:contacts][contact_name.to_s] = {name: contact_name.to_s, type: contact_type,
|
|
34
|
+
contact: contact, opts: contact_opts}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def contact_group(contact_group_name, &block)
|
|
38
|
+
c = Eye::Dsl::ConfigOpts.new nil, self, false
|
|
39
|
+
c.instance_eval(&block)
|
|
40
|
+
cfg = c.config
|
|
41
|
+
@config[:contacts] ||= {}
|
|
42
|
+
if cfg[:contacts].present?
|
|
43
|
+
@config[:contacts][contact_group_name.to_s] = cfg[:contacts].values
|
|
44
|
+
@config[:contacts].merge!(cfg[:contacts])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
10
47
|
|
|
11
48
|
end
|
data/lib/eye/dsl/opts.rb
CHANGED
|
@@ -2,24 +2,19 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
2
2
|
|
|
3
3
|
STR_OPTIONS = [ :pid_file, :working_dir, :stdout, :stderr, :stdall, :start_command,
|
|
4
4
|
:stop_command, :restart_command ]
|
|
5
|
-
|
|
6
5
|
create_options_methods(STR_OPTIONS, String)
|
|
7
6
|
|
|
8
7
|
BOOL_OPTIONS = [ :daemonize, :keep_alive, :control_pid, :auto_start, :stop_on_delete]
|
|
9
|
-
|
|
10
8
|
create_options_methods(BOOL_OPTIONS, [TrueClass, FalseClass])
|
|
11
9
|
|
|
12
10
|
INTERVAL_OPTIONS = [ :check_alive_period, :start_timeout, :restart_timeout, :stop_timeout, :start_grace,
|
|
13
11
|
:restart_grace, :stop_grace, :childs_update_period ]
|
|
14
|
-
|
|
15
12
|
create_options_methods(INTERVAL_OPTIONS, [Fixnum, Float])
|
|
16
13
|
|
|
17
14
|
OTHER_OPTIONS = [ :environment, :stop_signals ]
|
|
18
|
-
|
|
19
15
|
create_options_methods(OTHER_OPTIONS)
|
|
20
16
|
|
|
21
17
|
|
|
22
|
-
|
|
23
18
|
def initialize(name = nil, parent = nil)
|
|
24
19
|
super(name, parent)
|
|
25
20
|
|
|
@@ -70,6 +65,18 @@ class Eye::Dsl::Opts < Eye::Dsl::PureOpts
|
|
|
70
65
|
@config[:triggers].try :delete, type
|
|
71
66
|
end
|
|
72
67
|
|
|
68
|
+
def notify(contact, level = :crit)
|
|
69
|
+
raise Eye::Dsl::Error, "level should be in #{[:warn, :crit]}" unless Eye::Process::Notify::LEVELS[level]
|
|
70
|
+
|
|
71
|
+
@config[:notify] ||= {}
|
|
72
|
+
@config[:notify][contact.to_s] = level
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def nonotify(contact)
|
|
76
|
+
@config[:notify] ||= {}
|
|
77
|
+
@config[:notify].delete(contact.to_s)
|
|
78
|
+
end
|
|
79
|
+
|
|
73
80
|
def set_environment(value)
|
|
74
81
|
raise Eye::Dsl::Error, "environment should be a hash, but not #{value.inspect}" unless value.is_a?(Hash)
|
|
75
82
|
@config[:environment] ||= {}
|
data/lib/eye/dsl/pure_opts.rb
CHANGED
|
@@ -43,13 +43,13 @@ class Eye::Dsl::PureOpts
|
|
|
43
43
|
attr_reader :name, :full_name
|
|
44
44
|
attr_reader :config, :parent
|
|
45
45
|
|
|
46
|
-
def initialize(name = nil, parent = nil)
|
|
46
|
+
def initialize(name = nil, parent = nil, merge_parent_config = true)
|
|
47
47
|
@name = name.to_s
|
|
48
48
|
@full_name = @name
|
|
49
49
|
|
|
50
50
|
if parent
|
|
51
51
|
@parent = parent
|
|
52
|
-
@config =
|
|
52
|
+
@config = merge_parent_config ? Eye::Utils::deep_clone(parent.config) : {}
|
|
53
53
|
@full_name = "#{parent.full_name}:#{@full_name}"
|
|
54
54
|
else
|
|
55
55
|
@config = {}
|
data/lib/eye/dsl/validate.rb
CHANGED
|
@@ -36,6 +36,11 @@ module Eye::Dsl::Validate
|
|
|
36
36
|
if dubl_names.present?
|
|
37
37
|
raise Eye::Dsl::Error, "dublicate names: #{dubl_names.inspect}"
|
|
38
38
|
end
|
|
39
|
+
|
|
40
|
+
# validate processes with their own validate
|
|
41
|
+
all_processes.each do |process_cfg|
|
|
42
|
+
Eye::Process.validate process_cfg
|
|
43
|
+
end
|
|
39
44
|
end
|
|
40
45
|
|
|
41
46
|
end
|
data/lib/eye/group.rb
CHANGED
data/lib/eye/group/chain.rb
CHANGED
data/lib/eye/notify.rb
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
class Eye::Notify
|
|
2
|
+
include Celluloid
|
|
3
|
+
include Eye::Logger::Helpers
|
|
4
|
+
extend Eye::Checker::Validation
|
|
5
|
+
|
|
6
|
+
autoload :Mail, 'eye/notify/mail'
|
|
7
|
+
autoload :Jabber, 'eye/notify/jabber'
|
|
8
|
+
|
|
9
|
+
TYPES = {:mail => "Mail", :jabber => "Jabber"}
|
|
10
|
+
|
|
11
|
+
def self.get_class(type)
|
|
12
|
+
klass = eval("Eye::Notify::#{TYPES[type]}") rescue nil
|
|
13
|
+
raise "Unknown notify #{type}" unless klass
|
|
14
|
+
klass
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.validate!(options)
|
|
18
|
+
get_class(options[:type]).validate(options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.notify(contact, message_h)
|
|
22
|
+
current_config = Eye::Control.current_config[:config] # Warning, using global reference here !!! (not so nice)
|
|
23
|
+
needed_hash = (current_config[:contacts] || {})[contact.to_s]
|
|
24
|
+
|
|
25
|
+
return if needed_hash.blank?
|
|
26
|
+
|
|
27
|
+
create_proc = lambda do |nh|
|
|
28
|
+
type = nh[:type]
|
|
29
|
+
config = (current_config[type] || {}).merge(nh[:opts] || {}).merge(:contact => nh[:contact])
|
|
30
|
+
klass = get_class(type)
|
|
31
|
+
notify = klass.new(config, message_h)
|
|
32
|
+
notify.async_notify if notify
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if needed_hash.is_a?(Array)
|
|
36
|
+
needed_hash.each{|nh| create_proc[nh] }
|
|
37
|
+
else
|
|
38
|
+
create_proc[needed_hash]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
TIMEOUT = 1.minute
|
|
43
|
+
|
|
44
|
+
def initialize(options = {}, message_h = {})
|
|
45
|
+
@logger = Eye::Logger.new("#{self.class.name.downcase} - #{options[:contact]}")
|
|
46
|
+
debug "created notifier #{options}"
|
|
47
|
+
|
|
48
|
+
@message_h = message_h
|
|
49
|
+
@options = options
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def async_notify
|
|
53
|
+
async.notify
|
|
54
|
+
after(TIMEOUT){ terminate }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def notify
|
|
58
|
+
debug "start notify #{@message_h}"
|
|
59
|
+
execute
|
|
60
|
+
debug "end notify #{@message_h}"
|
|
61
|
+
terminate
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def execute
|
|
65
|
+
raise "realize me"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
param :contact, [String]
|
|
69
|
+
|
|
70
|
+
def message_subject
|
|
71
|
+
"[#{msg_host}] [#{msg_full_name}] #{msg_message}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def message_body
|
|
75
|
+
"#{message_subject} at #{msg_at.to_s(:short)}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
%w{at host message name full_name pid level}.each do |name|
|
|
81
|
+
define_method("msg_#{name}") do
|
|
82
|
+
@message_h[name.to_sym]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Eye::Notify::Jabber < Eye::Notify
|
|
2
|
+
|
|
3
|
+
# Eye.config do
|
|
4
|
+
# jabber :host => "some.host", :port => 12345, :user => "eye@some.host", :password => "123456"
|
|
5
|
+
# contact :vasya, :jabber, "vasya@some.host"
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
param :host, String, true
|
|
9
|
+
param :port, [String, Fixnum], true
|
|
10
|
+
param :user, String, true
|
|
11
|
+
param :password, String
|
|
12
|
+
|
|
13
|
+
def execute
|
|
14
|
+
require 'xmpp4r'
|
|
15
|
+
|
|
16
|
+
debug "send jabber #{[host, port, user, password]} - #{[contact, message_body]}"
|
|
17
|
+
|
|
18
|
+
mes = ::Jabber::Message.new(contact, message_body)
|
|
19
|
+
mes.set_type(:normal)
|
|
20
|
+
mes.set_id('1')
|
|
21
|
+
mes.set_subject(message_subject)
|
|
22
|
+
|
|
23
|
+
client = ::Jabber::Client.new(::Jabber::JID.new("#{user}/Eye"))
|
|
24
|
+
client.connect(host, port)
|
|
25
|
+
client.auth(password)
|
|
26
|
+
client.send(mes)
|
|
27
|
+
client.close
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'net/smtp'
|
|
2
|
+
|
|
3
|
+
class Eye::Notify::Mail < Eye::Notify
|
|
4
|
+
|
|
5
|
+
# Eye.config do
|
|
6
|
+
# mail :host => "some.host", :port => 12345, :user => "eye@some.host", :password => "123456", :domain => "some.host"
|
|
7
|
+
# contact :vasya, :mail, "vasya@some.host"
|
|
8
|
+
# end
|
|
9
|
+
|
|
10
|
+
param :host, String, true
|
|
11
|
+
param :port, [String, Fixnum], true
|
|
12
|
+
|
|
13
|
+
param :domain, String
|
|
14
|
+
param :user, String
|
|
15
|
+
param :password, String
|
|
16
|
+
param :auth, Symbol # :plain, :login, :cram_md5
|
|
17
|
+
|
|
18
|
+
param :from_mail, String
|
|
19
|
+
param :from_name, String, nil, 'eye'
|
|
20
|
+
|
|
21
|
+
def execute
|
|
22
|
+
smtp
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def smtp
|
|
26
|
+
args = [host, port, domain, user, password, auth]
|
|
27
|
+
debug "called smtp with #{args}"
|
|
28
|
+
|
|
29
|
+
Net::SMTP.start(*args) do |smtp|
|
|
30
|
+
smtp.send_message(message, from_mail || user, contact)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def message
|
|
35
|
+
h = []
|
|
36
|
+
h << "From: #{from_name} <#{from_mail || user}>" if from_mail || user
|
|
37
|
+
h << "To: <#{contact}>"
|
|
38
|
+
h << "Subject: #{message_subject}"
|
|
39
|
+
h << "Date: #{msg_at.httpdate}"
|
|
40
|
+
h << "Message-Id: <#{rand(1000000000).to_s(36)}.#{$$}.#{contact}>"
|
|
41
|
+
"#{h * "\n"}\n#{message_body}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
data/lib/eye/process.rb
CHANGED
|
@@ -15,6 +15,7 @@ class Eye::Process
|
|
|
15
15
|
autoload :Trigger, 'eye/process/trigger'
|
|
16
16
|
autoload :Notify, 'eye/process/notify'
|
|
17
17
|
autoload :Scheduler, 'eye/process/scheduler'
|
|
18
|
+
autoload :Validate, 'eye/process/validate'
|
|
18
19
|
|
|
19
20
|
attr_accessor :pid, :watchers, :config, :states_history,
|
|
20
21
|
:childs, :triggers, :flapping, :name
|
|
@@ -24,7 +25,7 @@ class Eye::Process
|
|
|
24
25
|
|
|
25
26
|
@config = prepare_config(config)
|
|
26
27
|
@logger = Eye::Logger.new(full_name)
|
|
27
|
-
|
|
28
|
+
|
|
28
29
|
@watchers = {}
|
|
29
30
|
@childs = {}
|
|
30
31
|
@triggers = []
|
|
@@ -77,6 +78,9 @@ class Eye::Process
|
|
|
77
78
|
|
|
78
79
|
# scheduler
|
|
79
80
|
include Eye::Process::Scheduler
|
|
81
|
+
|
|
82
|
+
# validate
|
|
83
|
+
extend Eye::Process::Validate
|
|
80
84
|
end
|
|
81
85
|
|
|
82
86
|
# include state_machine states
|
data/lib/eye/process/child.rb
CHANGED
|
@@ -35,10 +35,7 @@ module Eye::Process::Child
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
if removed_childs.present?
|
|
38
|
-
removed_childs.each
|
|
39
|
-
child = self.childs.delete(child_pid)
|
|
40
|
-
child.delete if child && child.alive?
|
|
41
|
-
end
|
|
38
|
+
removed_childs.each{|child_pid| remove_child(child_pid) }
|
|
42
39
|
end
|
|
43
40
|
|
|
44
41
|
h = {:new => new_childs.size, :removed => removed_childs.size, :exists => exist_childs.size }
|
|
@@ -49,13 +46,15 @@ module Eye::Process::Child
|
|
|
49
46
|
|
|
50
47
|
def remove_childs
|
|
51
48
|
if childs.present?
|
|
52
|
-
childs.keys.each
|
|
53
|
-
child = childs.delete(child_pid)
|
|
54
|
-
child.delete if child && child.alive?
|
|
55
|
-
end
|
|
49
|
+
childs.keys.each{|child_pid| remove_child(child_pid) }
|
|
56
50
|
else
|
|
57
51
|
debug 'No childs to clear'
|
|
58
52
|
end
|
|
59
53
|
end
|
|
60
54
|
|
|
55
|
+
def remove_child(child_pid)
|
|
56
|
+
child = self.childs.delete(child_pid)
|
|
57
|
+
child.destroy if child && child.alive?
|
|
58
|
+
end
|
|
59
|
+
|
|
61
60
|
end
|