spawn_server 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/spawn/server.rb +49 -15
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.1.0
|
data/lib/spawn/server.rb
CHANGED
@@ -4,20 +4,56 @@ require 'spawn/task'
|
|
4
4
|
module Spawn
|
5
5
|
class Server
|
6
6
|
POLLING_INTERVAL = 60
|
7
|
+
LOG_FILE = 'log/overlord.out'
|
7
8
|
|
8
9
|
attr_accessor :pids
|
9
10
|
attr_accessor :tasks
|
10
11
|
attr_accessor :interval
|
11
12
|
attr_accessor :start_times
|
12
13
|
|
13
|
-
def initialize(tasks, interval=POLLING_INTERVAL)
|
14
|
-
|
14
|
+
def initialize(tasks, interval=POLLING_INTERVAL, detach=false)
|
15
|
+
logger.debug "Initializing spawn server"
|
15
16
|
|
16
17
|
self.pids = {}
|
17
18
|
self.start_times = {}
|
18
19
|
self.tasks = tasks
|
19
20
|
self.interval = interval
|
20
21
|
|
22
|
+
if detach
|
23
|
+
# kill any previously running instance
|
24
|
+
overlord_pid_file = pid_file('overlord', 1)
|
25
|
+
if File.file?(overlord_pid_file)
|
26
|
+
old_pid = File.open(overlord_pid_file).read.to_i
|
27
|
+
begin
|
28
|
+
Process.kill('HUP', old_pid)
|
29
|
+
rescue Exception => e
|
30
|
+
STDERR.puts "No such process #{old_pid}"
|
31
|
+
end
|
32
|
+
else
|
33
|
+
old_pid = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
pid = Process.fork do
|
37
|
+
Process.setsid
|
38
|
+
STDIN.close
|
39
|
+
|
40
|
+
File.open(LOG_FILE, 'w') do |f|
|
41
|
+
STDERR.reopen f
|
42
|
+
STDOUT.reopen f
|
43
|
+
end
|
44
|
+
|
45
|
+
init_traps
|
46
|
+
start_tasks
|
47
|
+
end
|
48
|
+
|
49
|
+
File.open(overlord_pid_file,"w"){|f| f.puts pid }
|
50
|
+
else
|
51
|
+
init_traps
|
52
|
+
start_tasks
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def init_traps
|
21
57
|
# trap INT for debugging, in production we want to leave children active
|
22
58
|
Signal.trap('INT') do
|
23
59
|
process_list = self.pids.map{|k,v| "#{k} (#{v})" }.join(', ')
|
@@ -25,8 +61,6 @@ module Spawn
|
|
25
61
|
Process.kill('INT', *self.pids.values.map{|h| h.keys }.flatten )
|
26
62
|
exit(1)
|
27
63
|
end
|
28
|
-
|
29
|
-
start_tasks
|
30
64
|
end
|
31
65
|
|
32
66
|
def logger
|
@@ -40,7 +74,7 @@ module Spawn
|
|
40
74
|
end
|
41
75
|
|
42
76
|
def start_tasks
|
43
|
-
|
77
|
+
logger.debug self.tasks.inspect
|
44
78
|
|
45
79
|
# first load in pid files
|
46
80
|
self.tasks.each do |id, params|
|
@@ -49,7 +83,7 @@ module Spawn
|
|
49
83
|
params[:max_threads].times do |thread_num|
|
50
84
|
thread_pid_file = pid_file(id, thread_num+1)
|
51
85
|
|
52
|
-
|
86
|
+
logger.debug thread_pid_file
|
53
87
|
|
54
88
|
if File.exists?(thread_pid_file)
|
55
89
|
pid = File.open(thread_pid_file).read.to_i
|
@@ -72,7 +106,7 @@ module Spawn
|
|
72
106
|
process_stop(id, pid, false)
|
73
107
|
end
|
74
108
|
else
|
75
|
-
|
109
|
+
logger.debug "Unrecognized value for :reload parameter in #{id}: #{params[:reload]}"
|
76
110
|
end
|
77
111
|
end
|
78
112
|
end
|
@@ -80,16 +114,16 @@ module Spawn
|
|
80
114
|
loop do
|
81
115
|
Thread.new do
|
82
116
|
self.tasks.each do |id, params|
|
83
|
-
|
117
|
+
logger.debug "Checking if #{id} is running"
|
84
118
|
|
85
119
|
if (!process_running?(id, params[:max_threads]))
|
86
|
-
|
120
|
+
logger.debug "It's not, starting..."
|
87
121
|
# not running, or not enough running, start it...
|
88
122
|
process_start(id, params) do
|
89
123
|
if params[:task].is_a?(String)
|
90
124
|
Rake::Task[params[:task]].invoke
|
91
125
|
elsif params[:task].is_a?(Proc)
|
92
|
-
|
126
|
+
logger.debug "Initializing task #{id}"
|
93
127
|
params[:task].call
|
94
128
|
end
|
95
129
|
exit
|
@@ -99,9 +133,9 @@ module Spawn
|
|
99
133
|
# check if the processes are running too long, this needs to be done after "process_running" is called so that the pid list is cleared, it's not optimal this way but good enough for now
|
100
134
|
self.pids[id].each do |pid,mtime|
|
101
135
|
if params[:max_life] && params[:max_life] < time_running(id,pid)
|
102
|
-
|
136
|
+
logger.debug "Before process stop (#{pid}):\n#{process_list}"
|
103
137
|
process_stop(id,pid)
|
104
|
-
|
138
|
+
logger.debug "After process stop (#{pid}):\n#{process_list}"
|
105
139
|
|
106
140
|
# BackgroundCheck.deliver_process_max_life(id, time_running(id,pid), params[:max_life]) rescue nil
|
107
141
|
end
|
@@ -172,7 +206,7 @@ module Spawn
|
|
172
206
|
end
|
173
207
|
end
|
174
208
|
|
175
|
-
|
209
|
+
logger.debug "Stopping process #{pid} (#{id})"
|
176
210
|
Process.kill(9, pid) rescue nil
|
177
211
|
end
|
178
212
|
|
@@ -184,7 +218,7 @@ module Spawn
|
|
184
218
|
end
|
185
219
|
pid = pid.handle.to_i
|
186
220
|
|
187
|
-
|
221
|
+
logger.debug "Started process #{pid} (#{id})"
|
188
222
|
begin
|
189
223
|
params[:max_threads].times do |thread_num|
|
190
224
|
thread_pid_file = pid_file(id, thread_num+1)
|
@@ -197,7 +231,7 @@ module Spawn
|
|
197
231
|
end
|
198
232
|
rescue Exception => e
|
199
233
|
# email this log message
|
200
|
-
|
234
|
+
logger.debug e.message
|
201
235
|
end
|
202
236
|
self.pids[id][pid] = Time.now
|
203
237
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spawn_server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jeff Moss
|