trident 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c1497896041247b078fad1afd3814676a75819c7
4
- data.tar.gz: 7fc6cc36f0a02b4088270ed5466e67d2f33b8bdd
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDdmMDA1Y2YzMDI4YzcyM2VkZDIyNmNjZTViYzVjZWJiZDAyNzE1Yw==
5
+ data.tar.gz: !binary |-
6
+ NDUxYTk3ZGE5ZTRjZWNhZDVkMmEwYWY4Yjg5NTFhOTBiYWQyMjg4Ng==
5
7
  SHA512:
6
- metadata.gz: c462d1e488d09b3779dee1c44a378aaf65ea41f8b283fe98fcf091d1e351dd6a8150ff11e61bf26396f110de13b718d39db3d31c4da1eb0b584daf5201172fb6
7
- data.tar.gz: a2686b40f96950edc600388daa311487c08f932666524b4c050b2bd9cfd70ae5ed6baa0f3217b26fd8c15d82e262343aa7d78c6ef60f9dfafdf562d0157ba659
8
+ metadata.gz: !binary |-
9
+ OWRhNzgzNzY4ODZkZDZjZGU1ZmZlMzQxMTA5ZGFmNDUyMjA4Yjc4YzMxNmFm
10
+ OTg4Y2VkNTdkZjU0MmM2ODc1NjRhNjM3ZWJiOWZiN2EzMzc2NDY0ZWU3NmY3
11
+ MjYxYmY5YWQ4ZjZjY2Y2M2MzNjA1OWFkNGJiNTI1MGU4ZDlkYTY=
12
+ data.tar.gz: !binary |-
13
+ ZjE0YzhiYzU0OWRjN2M3NTE0ZmIyMzBiNmJiNzI2ZGM2ODk2NjVjZjRlZDAy
14
+ MjEwNTc5MmQ2ZWVkNTdiNWYyYTRmYzEyNzcyMmY4YWFkNTMxMjliZTc3ZTQ3
15
+ MjZkZjFlOWQ0MzZhZWI5NWQ3NjUyMTdkYTZiMzMyYTE5M2QwZmU=
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
4
  - 1.9.3
4
5
  - 2.0.0
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 0.3.0 (11/19/2013)
2
+ ------------------
3
+
4
+ fix race condition on startup for installing signal handlers before fork tries to reset them <dab3f0f> [Matt Conway]
5
+ fix require needed for 1.9.3 <7230dfc> [Matt Conway]
6
+
1
7
  0.2.0 (11/18/2013)
2
8
  ------------------
3
9
 
data/README.md CHANGED
@@ -36,3 +36,4 @@ See other command line options with
36
36
 
37
37
  * Add support for reloading the trident config with a HUP signal
38
38
  * Add support in yml for specifying [process limits](http://www.ruby-doc.org/core-1.9.3/Process.html#method-c-setrlimit) (memory especially)
39
+ * Add ability to track pool processes across a restart (or maybe only across a HUP) - allows a restart to spin up new processes as old ones die off gracefully.
@@ -69,9 +69,9 @@ module Trident
69
69
  manager = Trident::PoolManager.new(config_hash['application'],
70
70
  pools.values,
71
71
  config_hash['prefork'] == true)
72
- sh_thread = Thread.new { Trident::SignalHandler.start(config_hash['signals'], manager) }
72
+ Trident::SignalHandler.start(config_hash['signals'], manager)
73
73
  manager.start
74
- sh_thread.join
74
+ Trident::SignalHandler.join
75
75
  end
76
76
 
77
77
  private
@@ -1,3 +1,5 @@
1
+ require 'fcntl'
2
+
1
3
  module Trident
2
4
  class SignalHandler
3
5
  include GemLogger::LoggerSupport
@@ -24,6 +26,12 @@ module Trident
24
26
  self.instance = nil
25
27
  end
26
28
 
29
+ def join
30
+ raise "No signal handler started" unless instance
31
+ logger.info "Joining on signal handler"
32
+ instance.join
33
+ end
34
+
27
35
  def reset_for_fork
28
36
  raise "No signal handler started" unless instance
29
37
  instance.reset_for_fork
@@ -39,6 +47,7 @@ module Trident
39
47
  @signal_queue = []
40
48
  @self_pipe = []
41
49
  @original_signal_handlers = {}
50
+ @main_loop = nil
42
51
  self.signal_mappings = signal_mappings
43
52
  end
44
53
 
@@ -46,16 +55,18 @@ module Trident
46
55
  setup_self_pipe
47
56
  setup_signal_handlers
48
57
 
49
- logger.info "Main loop started"
50
- loop do
51
- signal_result = handle_signal_queue
52
- break if signal_result == :break
53
- logger.debug "Snoozing main loop"
54
- msg = snooze if signal_queue.empty?
55
- logger.debug "Main loop awakened: #{msg.inspect}"
56
- break if msg == MSG_STOP
58
+ @main_loop = Thread.new do
59
+ logger.info "Main loop started"
60
+ loop do
61
+ signal_result = handle_signal_queue
62
+ break if signal_result == :break
63
+ logger.debug "Snoozing main loop"
64
+ msg = snooze if signal_queue.empty?
65
+ logger.debug "Main loop awakened: #{msg.inspect}"
66
+ break if msg == MSG_STOP
67
+ end
68
+ logger.info "Main loop exited"
57
69
  end
58
- logger.info "Main loop exited"
59
70
  end
60
71
 
61
72
  def stop
@@ -63,6 +74,10 @@ module Trident
63
74
  wakeup(MSG_STOP)
64
75
  end
65
76
 
77
+ def join
78
+ @main_loop.join
79
+ end
80
+
66
81
  def reset_for_fork
67
82
  @self_pipe = []
68
83
  reset_signal_handlers
@@ -1,3 +1,3 @@
1
1
  module Trident
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -103,23 +103,31 @@ def wait_for(io, pattern)
103
103
  end
104
104
  end
105
105
 
106
- def child_processes(pid=Process.pid)
106
+ def child_processes(root_pid=Process.pid)
107
107
  processes = {}
108
- lines = `pstree -w #{pid}`.lines.to_a
109
- # lines = `ps -g #{pid} -opid,command`.lines.to_a
110
- lines.shift # get rid of header
108
+ relations = {}
109
+ lines = `ps -e -o pid,ppid,command`.lines.to_a
110
+ lines.shift # remove header
111
111
  lines.each do |line|
112
- pieces = line.scan(/\A[^\d]*(\d+) \w+ (.*)\Z/).first
113
- pid = pieces.shift
114
- pid = pid.to_i
115
- raise "Failed to extract pid: #{line} - #{pieces}" if pid == 0
116
- next if pid == Process.pid
112
+ line.chomp!
113
+ pieces = line.scan(/(\d+)\s+(\d+)\s+(.*)/).first
114
+ pid = pieces[0].to_i
115
+ ppid = pieces[1].to_i
116
+ command = pieces[2].strip
117
117
 
118
- command = pieces.shift.strip
119
118
  next if command =~ /^ps/
119
+
120
120
  processes[pid] = command
121
+ relations[ppid] ||= []
122
+ relations[ppid] << pid
123
+ end
124
+
125
+ pids = Array(relations[root_pid])
126
+ pids.each do |pid|
127
+ pids.concat(Array(relations[pid]))
121
128
  end
122
- processes
129
+
130
+ processes.select {|k, v| pids.include?(k) }
123
131
  end
124
132
 
125
133
  def kill_all_child_processes
@@ -249,6 +249,7 @@ class Trident::CLITest < MiniTest::Should::TestCase
249
249
  should "run if given logfile and pidfile when daemonizing" do
250
250
 
251
251
  Trident::SignalHandler.expects(:start).once
252
+ Trident::SignalHandler.expects(:join).once
252
253
  Trident::Pool.any_instance.stubs(:fork)
253
254
  Trident::CLI.any_instance.expects(:daemonize).once
254
255
 
@@ -188,12 +188,13 @@ class Trident::SignalHandlerTest < MiniTest::Should::TestCase
188
188
 
189
189
  end
190
190
 
191
- context "#start/stop" do
191
+ context "#start/stop/join" do
192
192
 
193
193
  should "block until woken" do
194
194
  handler = SignalHandler.new({}, Target.new)
195
195
  handler.stubs(:trap)
196
- thread = Thread.new { handler.start }
196
+ handler.start
197
+ thread = Thread.new { handler.join }
197
198
  sleep 0.1
198
199
  assert thread.alive?
199
200
  handler.stop
@@ -221,12 +222,22 @@ class Trident::SignalHandlerTest < MiniTest::Should::TestCase
221
222
 
222
223
  end
223
224
 
225
+ context ".join" do
226
+
227
+ should "fail if already instantiated" do
228
+ SignalHandler.instance = nil
229
+ assert_raises(RuntimeError) { SignalHandler.join }
230
+ end
231
+
232
+ end
233
+
224
234
  context "api" do
225
235
 
226
236
  should "react to signals" do
227
237
  fc = ForkChild.new do
228
238
  target = Target.new
229
239
  SignalHandler.start({"int" => "foo", "term" => "bar", "usr1" => "action_break"}, target)
240
+ SignalHandler.join
230
241
  target.received
231
242
  end
232
243
 
@@ -246,6 +257,7 @@ class Trident::SignalHandlerTest < MiniTest::Should::TestCase
246
257
  $stderr.reopen("/dev/null")
247
258
  target = Target.new
248
259
  SignalHandler.start({"int" => "foo", "term" => "bar", "usr1" => "action_break"}, target)
260
+ SignalHandler.join
249
261
  target.received
250
262
  end
251
263
  sleep 0.1
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trident
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Conway
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-18 00:00:00.000000000 Z
11
+ date: 2013-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_logger
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: clamp
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
@@ -56,56 +56,56 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: minitest
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: minitest_should
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ! '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ! '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: minitest-reporters
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ! '>='
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description: Manages pools of forked ruby processes
@@ -156,17 +156,17 @@ require_paths:
156
156
  - lib
157
157
  required_ruby_version: !ruby/object:Gem::Requirement
158
158
  requirements:
159
- - - '>='
159
+ - - ! '>='
160
160
  - !ruby/object:Gem::Version
161
161
  version: '0'
162
162
  required_rubygems_version: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - '>='
164
+ - - ! '>='
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  requirements: []
168
168
  rubyforge_project:
169
- rubygems_version: 2.0.6
169
+ rubygems_version: 2.1.11
170
170
  signing_key:
171
171
  specification_version: 4
172
172
  summary: Manages pools of forked ruby processes
@@ -181,4 +181,3 @@ test_files:
181
181
  - test/unit/trident/pool_test.rb
182
182
  - test/unit/trident/signal_handler_test.rb
183
183
  - test/unit/trident/utils_test.rb
184
- has_rdoc: