sponges 0.5.0.1.pre → 0.5.0.2.pre
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/lib/sponges.rb +4 -1
- data/lib/sponges/commander.rb +1 -1
- data/lib/sponges/handler.rb +116 -0
- data/lib/sponges/runner.rb +0 -1
- data/lib/sponges/store/memory.rb +0 -2
- data/lib/sponges/supervisor.rb +11 -77
- data/lib/sponges/version.rb +1 -1
- metadata +3 -2
data/lib/sponges.rb
CHANGED
@@ -3,7 +3,9 @@ require 'boson/runner'
|
|
3
3
|
require 'socket'
|
4
4
|
require 'logger'
|
5
5
|
require 'machine'
|
6
|
+
require 'forwardable'
|
6
7
|
require_relative 'sponges/configuration'
|
8
|
+
require_relative 'sponges/handler'
|
7
9
|
require_relative 'sponges/supervisor'
|
8
10
|
require_relative 'sponges/runner'
|
9
11
|
require_relative 'sponges/commander'
|
@@ -13,7 +15,8 @@ require_relative 'sponges/store/memory'
|
|
13
15
|
require_relative 'sponges/store/redis'
|
14
16
|
|
15
17
|
module Sponges
|
16
|
-
|
18
|
+
STOP_SIGNALS = [:INT, :QUIT, :TERM]
|
19
|
+
SIGNALS = STOP_SIGNALS + [:HUP, :TTIN, :TTOU, :CHLD]
|
17
20
|
|
18
21
|
def configure(&block)
|
19
22
|
Sponges::Configuration.configure &block
|
data/lib/sponges/commander.rb
CHANGED
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Sponges
|
3
|
+
class Handler
|
4
|
+
extend Forwardable
|
5
|
+
attr_reader :supervisor
|
6
|
+
|
7
|
+
def initialize(supervisor)
|
8
|
+
@supervisor = supervisor
|
9
|
+
at_exit do
|
10
|
+
for_supervisor do
|
11
|
+
Sponges.logger.info "Supervisor exits."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(signal)
|
17
|
+
if Sponges::SIGNALS.include?(signal = find_signal(signal))
|
18
|
+
send "handler_#{signal.to_s.downcase}", signal
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def_delegators :@supervisor, :store, :fork_children, :name, :children_name
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def for_supervisor
|
27
|
+
yield if Process.pid == store.supervisor_pid
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_signal(signal)
|
31
|
+
return signal if signal.is_a?(Symbol)
|
32
|
+
if signal = Signal.list.find {|k,v| v == signal }
|
33
|
+
signal.first.to_sym
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def handler_ttin(signal)
|
38
|
+
for_supervisor do
|
39
|
+
Sponges.logger.warn "Supervisor increment child's pool by one."
|
40
|
+
fork_children
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def handler_ttou(signal)
|
45
|
+
for_supervisor do
|
46
|
+
Sponges.logger.warn "Supervisor decrement child's pool by one."
|
47
|
+
if store.children_pids.first
|
48
|
+
kill_one(store.children_pids.first, :HUP)
|
49
|
+
store.delete_children(store.children_pids.first)
|
50
|
+
else
|
51
|
+
Sponges.logger.warn "No more child to kill."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def handler_chld(signal)
|
57
|
+
for_supervisor do
|
58
|
+
store.children_pids.each do |pid|
|
59
|
+
begin
|
60
|
+
if dead = Process.waitpid(pid.to_i, Process::WNOHANG)
|
61
|
+
Sponges.logger.warn "Child #{dead} died. Restarting a new one..."
|
62
|
+
store.delete_children dead
|
63
|
+
Sponges::Hook.on_chld
|
64
|
+
fork_children
|
65
|
+
end
|
66
|
+
rescue Errno::ECHILD => e
|
67
|
+
# Don't panic
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def handler_int(signal)
|
74
|
+
Sponges.logger.info "Supervisor received #{signal} signal."
|
75
|
+
kill_them_all(signal)
|
76
|
+
Process.waitall
|
77
|
+
Sponges.logger.info "Children shutdown complete."
|
78
|
+
Sponges.logger.info "Supervisor shutdown. Exiting..."
|
79
|
+
store.clear(name)
|
80
|
+
exit
|
81
|
+
rescue Errno::ESRCH, Errno::ECHILD, SignalException => e
|
82
|
+
# Don't panic
|
83
|
+
end
|
84
|
+
|
85
|
+
alias handler_quit handler_int
|
86
|
+
alias handler_term handler_int
|
87
|
+
|
88
|
+
def kill_them_all(signal)
|
89
|
+
store.children_pids.each do |pid|
|
90
|
+
kill_one(pid.to_i, signal)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def kill_one(pid, signal)
|
95
|
+
begin
|
96
|
+
Process.kill signal, pid
|
97
|
+
Process.waitpid pid
|
98
|
+
Sponges.logger.info "Child #{pid} receive a #{signal} signal."
|
99
|
+
rescue Errno::ESRCH, Errno::ECHILD, SignalException => e
|
100
|
+
# Don't panic
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def fork_children
|
105
|
+
name = children_name
|
106
|
+
pid = fork do
|
107
|
+
$PROGRAM_NAME = name
|
108
|
+
(Sponges::STOP_SIGNALS + [:HUP]).each{ |sig| trap(sig) { exit!(0) } }
|
109
|
+
Sponges::Hook.after_fork
|
110
|
+
supervisor.call
|
111
|
+
end
|
112
|
+
Sponges.logger.info "Supervisor create a child with #{pid} pid."
|
113
|
+
store.add_children pid
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/sponges/runner.rb
CHANGED
data/lib/sponges/store/memory.rb
CHANGED
data/lib/sponges/supervisor.rb
CHANGED
@@ -1,111 +1,45 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Sponges
|
3
3
|
class Supervisor
|
4
|
-
attr_reader :store, :name, :options
|
4
|
+
attr_reader :store, :name, :options, :handler
|
5
5
|
|
6
6
|
def initialize(name, options, store, block)
|
7
7
|
@name, @options, @store, @block = name, options, store, block
|
8
|
+
$PROGRAM_NAME = "#{@name}_supervisor"
|
8
9
|
store.on_fork
|
9
10
|
store.register Process.pid
|
10
11
|
@children_seen = 0
|
12
|
+
@handler = Handler.new self
|
11
13
|
end
|
12
14
|
|
13
15
|
def start
|
14
16
|
trap_signals
|
15
|
-
at_exit do
|
16
|
-
Sponges.logger.info "Supervisor exits."
|
17
|
-
end
|
18
17
|
options[:size].times do
|
19
|
-
|
18
|
+
handler.call :TTIN
|
20
19
|
end
|
21
20
|
Sponges.logger.info "Supervisor started, waiting for messages."
|
22
21
|
sleep
|
23
22
|
rescue Exception => exception
|
24
23
|
Sponges.logger.error exception
|
25
|
-
|
24
|
+
handler.call :INT
|
26
25
|
raise exception
|
27
26
|
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
def fork_children
|
32
|
-
name = children_name
|
33
|
-
pid = fork do
|
34
|
-
$PROGRAM_NAME = name
|
35
|
-
(Sponges::SIGNALS + [:HUP]).each{ |sig| trap(sig) { exit!(0) } }
|
36
|
-
Sponges::Hook.after_fork
|
37
|
-
@block.call
|
38
|
-
end
|
39
|
-
Sponges.logger.info "Supervisor create a child with #{pid} pid."
|
40
|
-
store.add_children pid
|
28
|
+
def call
|
29
|
+
@block.call
|
41
30
|
end
|
42
31
|
|
32
|
+
private
|
33
|
+
|
43
34
|
def children_name
|
44
35
|
"#{name}_child_#{@children_seen +=1}"
|
45
36
|
end
|
46
37
|
|
47
38
|
def trap_signals
|
48
|
-
|
49
|
-
trap(signal)
|
50
|
-
handle_signal signal
|
51
|
-
end
|
52
|
-
end
|
53
|
-
trap(:TTIN) do
|
54
|
-
Sponges.logger.warn "Supervisor increment child's pool by one."
|
55
|
-
fork_children
|
56
|
-
end
|
57
|
-
trap(:TTOU) do
|
58
|
-
Sponges.logger.warn "Supervisor decrement child's pool by one."
|
59
|
-
if store.children_pids.first
|
60
|
-
kill_one(store.children_pids.first, :HUP)
|
61
|
-
store.delete_children(store.children_pids.first)
|
62
|
-
else
|
63
|
-
Sponges.logger.warn "No more child to kill."
|
64
|
-
end
|
65
|
-
end
|
66
|
-
trap(:CHLD) do
|
67
|
-
store.children_pids.each do |pid|
|
68
|
-
begin
|
69
|
-
dead = Process.waitpid(pid.to_i, Process::WNOHANG)
|
70
|
-
if dead
|
71
|
-
Sponges.logger.warn "Child #{dead} died. Restarting a new one..."
|
72
|
-
store.delete_children dead
|
73
|
-
Sponges::Hook.on_chld
|
74
|
-
fork_children
|
75
|
-
end
|
76
|
-
rescue Errno::ECHILD => e
|
77
|
-
# Don't panic
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def handle_signal(signal)
|
84
|
-
Sponges.logger.info "Supervisor received #{signal} signal."
|
85
|
-
kill_them_all(signal)
|
86
|
-
Process.waitall
|
87
|
-
Sponges.logger.info "Children shutdown complete."
|
88
|
-
Sponges.logger.info "Supervisor shutdown. Exiting..."
|
89
|
-
store.clear(name)
|
90
|
-
exit
|
91
|
-
rescue Errno::ESRCH, Errno::ECHILD, SignalException => e
|
92
|
-
# Don't panic
|
93
|
-
end
|
94
|
-
|
95
|
-
def kill_them_all(signal)
|
96
|
-
store.children_pids.each do |pid|
|
97
|
-
kill_one(pid.to_i, signal)
|
39
|
+
Sponges::SIGNALS.each do |signal|
|
40
|
+
trap(signal) {|signal| handler.call signal }
|
98
41
|
end
|
99
42
|
end
|
100
43
|
|
101
|
-
def kill_one(pid, signal)
|
102
|
-
begin
|
103
|
-
Process.kill signal, pid
|
104
|
-
Process.waitpid pid
|
105
|
-
Sponges.logger.info "Child #{pid} receive a #{signal} signal."
|
106
|
-
rescue Errno::ESRCH, Errno::ECHILD, SignalException => e
|
107
|
-
# Don't panic
|
108
|
-
end
|
109
|
-
end
|
110
44
|
end
|
111
45
|
end
|
data/lib/sponges/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sponges
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.0.
|
4
|
+
version: 0.5.0.2.pre
|
5
5
|
prerelease: 8
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: boson
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/sponges/cli.rb
|
76
76
|
- lib/sponges/commander.rb
|
77
77
|
- lib/sponges/configuration.rb
|
78
|
+
- lib/sponges/handler.rb
|
78
79
|
- lib/sponges/runner.rb
|
79
80
|
- lib/sponges/store.rb
|
80
81
|
- lib/sponges/store/memory.rb
|