We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Attempt to make the stress testing tool JRuby-compatible. It didn't work: 
JRuby is too flakey (and probably hpricot as well), but no harm in keeping 
the code around.
Hongli Lai (Phusion) (author)
Sun May 18 15:09:28 -0700 2008
commit  d24524f2b476f5a9401e2f1de7570914da184861
tree    5ed0c1c2429b7ca364b10f8cd32c7ab4acff8c62
parent  db907ab1111141f7dd6d3803ad92b53eae8f38a2
...
13
14
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
17
18
...
105
106
107
108
 
109
110
111
112
113
 
114
115
116
117
118
119
120
 
 
121
122
123
124
 
125
126
127
128
 
129
130
131
 
 
132
133
134
...
136
137
138
139
 
 
 
 
140
141
142
 
143
144
145
146
 
 
 
147
148
149
150
151
 
 
 
152
153
154
...
158
159
160
 
161
162
 
163
164
165
166
167
168
169
 
 
170
171
172
173
 
174
175
176
...
179
180
181
182
 
183
184
185
186
187
188
 
 
 
 
 
189
190
191
...
194
195
196
197
198
 
 
199
200
201
202
 
 
 
203
204
205
...
264
265
266
267
 
 
 
 
 
268
269
270
 
 
 
 
 
271
272
273
...
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
143
144
145
 
146
147
148
149
150
 
151
152
 
 
 
 
 
 
153
154
155
156
157
 
158
159
160
 
 
161
162
 
 
163
164
165
166
167
...
169
170
171
 
172
173
174
175
176
177
 
178
179
 
 
 
180
181
182
183
184
 
 
 
185
186
187
188
189
190
...
194
195
196
197
198
 
199
200
201
202
203
204
 
 
205
206
207
 
 
 
208
209
210
211
...
214
215
216
 
217
218
 
 
 
 
 
219
220
221
222
223
224
225
226
...
229
230
231
 
 
232
233
234
 
 
 
235
236
237
238
239
240
...
299
300
301
 
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
0
@@ -13,6 +13,44 @@ include Passenger
0
 include Passenger::Utils
0
 include PlatformInfo
0
 
0
+# A thread or a process, depending on the Ruby VM implementation.
0
+class Subprocess
0
+ attr_accessor :channel
0
+
0
+ def initialize(name, &block)
0
+ if RUBY_PLATFORM == "java"
0
+ a, b = UNIXSocket.pair
0
+ @thread = Thread.new do
0
+ block.call(true, MessageChannel.new(b))
0
+ end
0
+ @channel = MessageChannel.new(a)
0
+ @thread_channel = b
0
+ else
0
+ a, b = UNIXSocket.pair
0
+ @pid = safe_fork(name) do
0
+ a.close
0
+ $0 = name
0
+ Process.setsid
0
+ block.call(false, MessageChannel.new(b))
0
+ end
0
+ b.close
0
+ @channel = MessageChannel.new(a)
0
+ end
0
+ end
0
+
0
+ def stop
0
+ if RUBY_PLATFORM == "java"
0
+ @thread.terminate
0
+ @channel.close
0
+ @thread_channel.close
0
+ else
0
+ Process.kill('SIGKILL', @pid) rescue nil
0
+ Process.waitpid(@pid) rescue nil
0
+ @channel.close
0
+ end
0
+ end
0
+end
0
+
0
 class StressTester
0
   def start
0
     @options = parse_options
0
@@ -105,30 +143,25 @@ class StressTester
0
 
0
   def run_crawlers
0
     @started = false
0
- @processes = []
0
+ @crawlers = []
0
     
0
     # Start crawler processes.
0
     GC.start if GC.copy_on_write_friendly?
0
     @options[:concurrency].times do |i|
0
- STDOUT.write("Starting crawler #{i + 1} of #{@options[:concurrency]}...\r")
0
+ STDOUT.write("Starting crawler #{i + 1} of #{@options[:concurrency]}...\n")
0
       STDOUT.flush
0
- a, b = UNIXSocket.pair
0
- pid = safe_fork("crawler #{i + 1}") do
0
- a.close
0
- $0 = "Passenger Crawler #{i + 1}"
0
- Process.setsid
0
- if @options[:nice]
0
+ process = Subprocess.new("crawler #{i + 1}") do |is_thread, channel|
0
+ if !is_thread && @options[:nice]
0
           system("renice 1 #{Process.pid} >/dev/null 2>/dev/null")
0
         end
0
         while true
0
- crawl!(i + 1, MessageChannel.new(b))
0
+ crawl!(i + 1, channel)
0
         end
0
       end
0
- b.close
0
- @processes << {
0
+ @crawlers << {
0
         :id => i + 1,
0
- :channel => MessageChannel.new(a),
0
- :pid => pid,
0
+ :process => process,
0
+ :channel => process.channel,
0
         :mutex => Mutex.new,
0
         :current_uri => nil,
0
         :crawled => 0
0
@@ -136,19 +169,22 @@ class StressTester
0
     end
0
     
0
     puts
0
- sleep 1
0
+ if RUBY_PLATFORM != "java"
0
+ # 'sleep' b0rks when running in JRuby?
0
+ sleep 1
0
+ end
0
     begin
0
       $0 = "Passenger Crawler: control process"
0
- io_to_process = {}
0
+ io_to_crawler = {}
0
       ios = []
0
- @processes.each do |process|
0
- io_to_process[process[:channel].io] = process
0
- ios << process[:channel].io
0
+ @crawlers.each do |crawler|
0
+ io_to_crawler[crawler[:channel].io] = crawler
0
+ ios << crawler[:channel].io
0
       end
0
       
0
- # Tell each crawler process to start crawling.
0
- @processes.each do |process|
0
- process[:channel].write("start")
0
+ # Tell each crawler to start crawling.
0
+ @crawlers.each do |crawler|
0
+ crawler[:channel].write("start")
0
       end
0
       
0
       # Show progress periodically.
0
@@ -158,19 +194,18 @@ class StressTester
0
       apache_restarter = Thread.new(&method(:restart_apache))
0
       @next_app_restart = Time.now + @options[:app_restart_interval] * 60
0
       app_restarter = Thread.new(&method(:restart_app))
0
+
0
       while true
0
- note_progress(ios, io_to_process)
0
+ note_progress(ios, io_to_crawler)
0
       end
0
     rescue Interrupt
0
       trap('SIGINT') {}
0
       puts "Shutting down..."
0
       @done = true
0
- @processes.each do |process|
0
- STDOUT.write("Stopping crawler #{process[:id]} of #{@options[:concurrency]}...\r")
0
+ @crawlers.each do |crawler|
0
+ STDOUT.write("Stopping crawler #{crawler[:id]} of #{@options[:concurrency]}...\r")
0
         STDOUT.flush
0
- Process.kill('SIGKILL', process[:pid]) rescue nil
0
- Process.waitpid(process[:pid]) rescue nil
0
- process[:channel].close
0
+ crawler[:process].stop
0
       end
0
       progress_reporter.join if progress_reporter
0
       apache_restarter.join if apache_restarter
0
@@ -179,13 +214,13 @@ class StressTester
0
     end
0
   end
0
   
0
- def note_progress(ios, io_to_process)
0
+ def note_progress(ios, io_to_crawler)
0
     select(ios)[0].each do |io|
0
- process = io_to_process[io]
0
- uri = process[:channel].read[0]
0
- process[:mutex].synchronize do
0
- process[:current_uri] = uri
0
- process[:crawled] += 1
0
+ crawler = io_to_crawler[io]
0
+ uri = crawler[:channel].read[0]
0
+ crawler[:mutex].synchronize do
0
+ crawler[:current_uri] = uri
0
+ crawler[:crawled] += 1
0
       end
0
     end
0
   end
0
@@ -194,12 +229,12 @@ class StressTester
0
     while !@done
0
       output = "\n" * @terminal_height
0
       output << "### Running for #{duration(Time.now.to_i - @start_time.to_i)}\n"
0
- @processes.each do |process|
0
- process[:mutex].synchronize do
0
+ @crawlers.each do |crawler|
0
+ crawler[:mutex].synchronize do
0
           line = sprintf("Crawler %-2d: %-3d -> %s",
0
- process[:id],
0
- process[:crawled],
0
- process[:current_uri])
0
+ crawler[:id],
0
+ crawler[:crawled],
0
+ crawler[:current_uri])
0
           output << sprintf("%-#{@terminal_width}s\n", line)
0
         end
0
       end
0
@@ -264,10 +299,19 @@ class StressTester
0
         end
0
         channel.write(uri, referer, response)
0
       rescue
0
- Process.kill('SIGKILL', Process.pid)
0
+ if RUBY_PLATFORM == "java"
0
+ Thread.current.terminate
0
+ else
0
+ Process.kill('SIGKILL', Process.pid)
0
+ end
0
       end
0
     end
0
     crawler = Hawler.new(@options[:host], progress_reporter)
0
+ if RUBY_PLATFORM == "java"
0
+ trap('SIGINT') do
0
+ raise Interrupt, "Interrupted"
0
+ end
0
+ end
0
     crawler.recurse = true
0
     crawler.depth = @options[:depth]
0
     crawler.start
...
16
17
18
19
 
 
 
20
21
22
23
 
 
 
 
24
25
26
...
16
17
18
 
19
20
21
22
23
24
 
25
26
27
28
29
30
31
0
@@ -16,11 +16,16 @@
0
 
0
 require 'rubygems'
0
 require 'thread'
0
-require 'fastthread'
0
+if RUBY_PLATFORM != "java" && (RUBY_VERSION < "1.8.6" || (RUBY_VERSION == "1.8.6" && RUBY_PATCH_LEVEL < 110))
0
+ require 'fastthread'
0
+end
0
 require 'pathname'
0
 require 'etc'
0
 require 'passenger/exceptions'
0
-require 'passenger/native_support'
0
+if RUBY_PLATFORM != "java"
0
+ require 'passenger/native_support'
0
+end
0
+
0
 module Passenger
0
 
0
 # Utility functions.

Comments

    No one has commented yet.