puma 2.0.0.b1 → 2.0.0.b2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

@@ -1,3 +1,21 @@
1
+ === 2.0.0.b2 / 2012-11-18
2
+ * 5 minor feature:
3
+ * Now Puma is bundled with an capistrano recipe. Just require
4
+ 'puma/capistrano' in you deploy.rb
5
+ * Only inject CommonLogger in development mode
6
+ * Add -p option to pumactl
7
+ * Add ability to use pumactl to start a server
8
+ * Add options to daemonize puma
9
+
10
+ * 7 bug fixes:
11
+ * Reset the IOBuffer properly. Fixes #148
12
+ * Shutdown gracefully on JRuby with Ctrl-C
13
+ * Various methods to get newrelic to start. Fixes #128
14
+ * fixing syntax error at capistrano recipe
15
+ * Force ECONNRESET when read returns nil
16
+ * Be sure to empty the drain the todo before shutting down. Fixes #155
17
+ * allow for alternate locations for status app
18
+
1
19
  === 2.0.0.b1 / 2012-09-11
2
20
 
3
21
  * 1 major feature:
@@ -1,6 +1,5 @@
1
1
  COPYING
2
2
  Gemfile
3
- Gemfile.lock
4
3
  History.txt
5
4
  LICENSE
6
5
  Manifest.txt
data/README.md CHANGED
@@ -118,10 +118,16 @@ You should place code to close global log files, redis connections, etc in this
118
118
 
119
119
  If you start puma with `-S some/path` then you can pass that same path to the `pumactl` program to control your server. For instance:
120
120
 
121
- $ pumactl -S some/path restart
121
+ $ pumactl -S some/path command
122
+
123
+ or
124
+
125
+ $ pumactl -C url -T token command
122
126
 
123
127
  will cause the server to perform a restart. `pumactl` is a simple CLI frontend to the control/status app described above.
124
128
 
129
+ Allowed commands: status, restart, halt, stop
130
+
125
131
  ## Managing multiple Pumas / init.d script
126
132
 
127
133
  If you want an easy way to manage multiple scripts at once check [tools/jungle](https://github.com/puma/puma/tree/master/tools/jungle) for an init.d script.
data/Rakefile CHANGED
@@ -104,3 +104,14 @@ if IS_JRUBY
104
104
  else
105
105
  task :test => [:compile]
106
106
  end
107
+
108
+ namespace :test do
109
+ desc "Run the integration tests"
110
+ task :integration do
111
+ sh "cd test/shell; sh run.sh"
112
+ end
113
+
114
+ desc "Run all tests"
115
+ task :all => [:test, "test:integration"]
116
+ end
117
+
@@ -46,14 +46,17 @@ static VALUE buf_append(VALUE self, VALUE str) {
46
46
  if(new_size > b->size) {
47
47
  size_t n = b->size + (b->size / 2);
48
48
  uint8_t* top;
49
+ uint8_t* old;
49
50
 
50
51
  new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
51
52
 
52
53
  top = malloc(new_size);
53
- memcpy(top, b->top, used);
54
+ old = b->top;
55
+ memcpy(top, old, used);
54
56
  b->top = top;
55
57
  b->cur = top + used;
56
58
  b->size = new_size;
59
+ free(old);
57
60
  }
58
61
 
59
62
  memcpy(b->cur, RSTRING_PTR(str), str_len);
@@ -84,14 +87,17 @@ static VALUE buf_append2(int argc, VALUE* argv, VALUE self) {
84
87
  if(new_size > b->size) {
85
88
  size_t n = b->size + (b->size / 2);
86
89
  uint8_t* top;
90
+ uint8_t* old;
87
91
 
88
92
  new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
89
93
 
90
94
  top = malloc(new_size);
91
- memcpy(top, b->top, used);
95
+ old = b->top;
96
+ memcpy(top, old, used);
92
97
  b->top = top;
93
98
  b->cur = top + used;
94
99
  b->size = new_size;
100
+ free(old);
95
101
  }
96
102
 
97
103
  for(i = 0; i < argc; i++) {
@@ -21,15 +21,15 @@ module Puma
21
21
  end
22
22
 
23
23
  case env['PATH_INFO']
24
- when "/stop"
24
+ when /\/stop$/
25
25
  @server.stop
26
26
  return rack_response(200, OK_STATUS)
27
27
 
28
- when "/halt"
28
+ when /\/halt$/
29
29
  @server.halt
30
30
  return rack_response(200, OK_STATUS)
31
31
 
32
- when "/restart"
32
+ when /\/restart$/
33
33
  if @cli and @cli.restart_on_stop!
34
34
  @server.begin_restart
35
35
 
@@ -38,7 +38,7 @@ module Puma
38
38
  return rack_response(200, '{ "status": "not configured" }')
39
39
  end
40
40
 
41
- when "/stats"
41
+ when /\/stats$/
42
42
  b = @server.backlog
43
43
  r = @server.running
44
44
  return rack_response(200, %Q!{ "backlog": #{b}, "running": #{r} }!)
@@ -6,6 +6,7 @@ require 'puma/const'
6
6
  require 'puma/configuration'
7
7
  require 'puma/binder'
8
8
  require 'puma/detect'
9
+ require 'puma/daemon_ext'
9
10
 
10
11
  require 'rack/commonlogger'
11
12
  require 'rack/utils'
@@ -35,6 +36,8 @@ module Puma
35
36
 
36
37
  @restart = false
37
38
 
39
+ ENV['NEWRELIC_DISPATCHER'] ||= "puma"
40
+
38
41
  setup_options
39
42
 
40
43
  generate_restart_data
@@ -159,7 +162,9 @@ module Puma
159
162
  :quiet => false,
160
163
  :debug => false,
161
164
  :binds => [],
162
- :workers => 0
165
+ :workers => 0,
166
+ :daemon => false,
167
+ :environment => "development"
163
168
  }
164
169
 
165
170
  @parser = OptionParser.new do |o|
@@ -171,6 +176,38 @@ module Puma
171
176
  @options[:config_file] = arg
172
177
  end
173
178
 
179
+ o.on "--control URL", "The bind url to use for the control server",
180
+ "Use 'auto' to use temp unix server" do |arg|
181
+ if arg
182
+ @options[:control_url] = arg
183
+ elsif jruby?
184
+ unsupported "No default url available on JRuby"
185
+ end
186
+ end
187
+
188
+ o.on "--control-token TOKEN",
189
+ "The token to use as authentication for the control server" do |arg|
190
+ @options[:control_auth_token] = arg
191
+ end
192
+
193
+ o.on "-d", "--daemon", "Daemonize the server into the background" do
194
+ @options[:daemon] = true
195
+ @options[:quiet] = true
196
+ end
197
+
198
+ o.on "--debug", "Log lowlevel debugging information" do
199
+ @options[:debug] = true
200
+ end
201
+
202
+ o.on "--dir DIR", "Change to DIR before starting" do |d|
203
+ @options[:directory] = d.to_s
204
+ end
205
+
206
+ o.on "-e", "--environment ENVIRONMENT",
207
+ "The environment to run the Rack app on (default development)" do |arg|
208
+ @options[:environment] = arg
209
+ end
210
+
174
211
  o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg|
175
212
  $LOAD_PATH.unshift(*arg.split(':'))
176
213
  end
@@ -188,28 +225,16 @@ module Puma
188
225
  @options[:quiet] = true
189
226
  end
190
227
 
191
- o.on "--debug", "Log lowlevel debugging information" do
192
- @options[:debug] = true
228
+ o.on "--restart-cmd CMD",
229
+ "The puma command to run during a hot restart",
230
+ "Default: inferred" do |cmd|
231
+ @options[:restart_cmd] = cmd
193
232
  end
194
233
 
195
234
  o.on "-S", "--state PATH", "Where to store the state details" do |arg|
196
235
  @options[:state] = arg
197
236
  end
198
237
 
199
- o.on "--control URL", "The bind url to use for the control server",
200
- "Use 'auto' to use temp unix server" do |arg|
201
- if arg
202
- @options[:control_url] = arg
203
- elsif jruby?
204
- unsupported "No default url available on JRuby"
205
- end
206
- end
207
-
208
- o.on "--control-token TOKEN",
209
- "The token to use as authentication for the control server" do |arg|
210
- @options[:control_auth_token] = arg
211
- end
212
-
213
238
  o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
214
239
  min, max = arg.split(":")
215
240
  if max
@@ -229,16 +254,6 @@ module Puma
229
254
  @options[:workers] = arg.to_i
230
255
  end
231
256
 
232
- o.on "--restart-cmd CMD",
233
- "The puma command to run during a hot restart",
234
- "Default: inferred" do |cmd|
235
- @options[:restart_cmd] = cmd
236
- end
237
-
238
- o.on "-e", "--environment ENVIRONMENT",
239
- "The environment to run the Rack app on (default development)" do |arg|
240
- @options[:environment] = arg
241
- end
242
257
  end
243
258
 
244
259
  @parser.banner = "puma <options> <rackup file>"
@@ -311,6 +326,20 @@ module Puma
311
326
  log " - Goodbye!"
312
327
  end
313
328
 
329
+ def redirect_io
330
+ stdout = @options[:redirect_stdout]
331
+ stderr = @options[:redirect_stderr]
332
+ append = @options[:redirect_append]
333
+
334
+ if stdout
335
+ STDOUT.reopen stdout, (append ? "a" : "w")
336
+ end
337
+
338
+ if stderr
339
+ STDOUT.reopen stderr, (append ? "a" : "w")
340
+ end
341
+ end
342
+
314
343
  # Parse the options, load the rackup, start the server and wait
315
344
  # for it to finish.
316
345
  #
@@ -321,6 +350,10 @@ module Puma
321
350
  exit 1
322
351
  end
323
352
 
353
+ if dir = @options[:directory]
354
+ Dir.chdir dir
355
+ end
356
+
324
357
  clustered = @options[:workers] > 0
325
358
 
326
359
  if clustered
@@ -333,8 +366,6 @@ module Puma
333
366
  write_pid
334
367
  write_state
335
368
 
336
- @binder.parse @options[:binds], self
337
-
338
369
  if clustered
339
370
  run_cluster
340
371
  else
@@ -346,15 +377,17 @@ module Puma
346
377
  min_t = @options[:min_threads]
347
378
  max_t = @options[:max_threads]
348
379
 
380
+ log "Puma #{Puma::Const::PUMA_VERSION} starting..."
381
+ log "* Min threads: #{min_t}, max threads: #{max_t}"
382
+ log "* Environment: #{ENV['RACK_ENV']}"
383
+
384
+ @binder.parse @options[:binds], self
385
+
349
386
  server = Puma::Server.new @config.app, @events
350
387
  server.binder = @binder
351
388
  server.min_threads = min_t
352
389
  server.max_threads = max_t
353
390
 
354
- log "Puma #{Puma::Const::PUMA_VERSION} starting..."
355
- log "* Min threads: #{min_t}, max threads: #{max_t}"
356
- log "* Environment: #{ENV['RACK_ENV']}"
357
-
358
391
  @server = server
359
392
 
360
393
  if str = @options[:control_url]
@@ -407,7 +440,20 @@ module Puma
407
440
  log "*** Sorry signal SIGTERM not implemented, gracefully stopping feature disabled!"
408
441
  end
409
442
 
410
- log "Use Ctrl-C to stop"
443
+ if @options[:daemon]
444
+ Process.daemon(true)
445
+ else
446
+ log "Use Ctrl-C to stop"
447
+ end
448
+
449
+ redirect_io
450
+
451
+ if jruby?
452
+ Signal.trap("INT") do
453
+ graceful_stop server
454
+ exit
455
+ end
456
+ end
411
457
 
412
458
  begin
413
459
  server.run.join
@@ -504,6 +550,8 @@ module Puma
504
550
  log "* Min threads: #{@options[:min_threads]}, max threads: #{@options[:max_threads]}"
505
551
  log "* Environment: #{ENV['RACK_ENV']}"
506
552
 
553
+ @binder.parse @options[:binds], self
554
+
507
555
  @master_pid = Process.pid
508
556
 
509
557
  read, write = IO.pipe
@@ -538,9 +586,20 @@ module Puma
538
586
  #
539
587
  @check_pipe, @suicide_pipe = IO.pipe
540
588
 
589
+ if @options[:daemon]
590
+ Process.daemon(true)
591
+ else
592
+ log "Use Ctrl-C to stop"
593
+ end
594
+
595
+ redirect_io
596
+
541
597
  spawn_workers
542
598
 
543
- log "* Use Ctrl-C to stop"
599
+ Signal.trap "SIGINT" do
600
+ stop = true
601
+ write.write "!"
602
+ end
544
603
 
545
604
  begin
546
605
  while !stop
@@ -67,7 +67,7 @@ module Puma
67
67
  end
68
68
  end
69
69
 
70
- unless @options[:quiet]
70
+ if !@options[:quiet] and @options[:environment] == "development"
71
71
  logger = @options[:logger] || STDOUT
72
72
  app = Rack::CommonLogger.new(app, logger)
73
73
  end
@@ -156,6 +156,12 @@ module Puma
156
156
  @options[:binds] << url
157
157
  end
158
158
 
159
+ # Daemonize the server into the background. Highly suggest that
160
+ # this be combined with +pidfile+ and +stdout_redirect+.
161
+ def daemonize(which=true)
162
+ @options[:daemon] = which
163
+ end
164
+
159
165
  # Set the environment in which the Rack's app will run.
160
166
  def environment(environment)
161
167
  @options[:environment] = environment
@@ -187,6 +193,13 @@ module Puma
187
193
  @options[:rackup] = path.to_s
188
194
  end
189
195
 
196
+ # Redirect STDOUT and STDERR to files specified.
197
+ def stdout_redirect(stdout=nil, stderr=nil, append=false)
198
+ @options[:redirect_stdout] = stdout
199
+ @options[:redirect_stderr] = stderr
200
+ @options[:redirect_append] = append
201
+ end
202
+
190
203
  # Configure +min+ to be the minimum number of threads to use to answer
191
204
  # requests and +max+ the maximum.
192
205
  #
@@ -220,6 +233,11 @@ module Puma
220
233
  def workers(count)
221
234
  @options[:workers] = count.to_i
222
235
  end
236
+
237
+ # The directory to operate out of.
238
+ def directory(dir)
239
+ @options[:directory] = dir.to_s
240
+ end
223
241
  end
224
242
  end
225
243
  end
@@ -28,7 +28,7 @@ module Puma
28
28
  # too taxing on performance.
29
29
  module Const
30
30
 
31
- PUMA_VERSION = VERSION = "2.0.0.b1".freeze
31
+ PUMA_VERSION = VERSION = "2.0.0.b2".freeze
32
32
 
33
33
  FAST_TRACK_KA_TIMEOUT = 0.2
34
34
 
@@ -1,127 +1,212 @@
1
1
  require 'optparse'
2
-
3
2
  require 'puma/const'
4
3
  require 'puma/configuration'
5
-
6
4
  require 'yaml'
7
5
  require 'uri'
8
-
9
6
  require 'socket'
10
-
11
7
  module Puma
12
8
  class ControlCLI
13
9
 
14
- def initialize(argv, stdout=STDOUT)
10
+ COMMANDS = %w{halt restart start stats status stop}
11
+
12
+ def is_windows?
13
+ RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
14
+ end
15
+
16
+ def initialize(argv, stdout=STDOUT, stderr=STDERR)
15
17
  @argv = argv
16
18
  @stdout = stdout
17
- end
19
+ @stderr = stderr
20
+ @options = {}
21
+
22
+ opts = OptionParser.new do |o|
23
+ o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token) (#{COMMANDS.join("|")})"
18
24
 
19
- def setup_options
20
- @parser = OptionParser.new do |o|
21
25
  o.on "-S", "--state PATH", "Where the state file to use is" do |arg|
22
- @path = arg
26
+ @options[:status_path] = arg
23
27
  end
24
- end
25
- end
26
28
 
27
- def connect
28
- if str = @config.options[:control_url]
29
- uri = URI.parse str
30
- case uri.scheme
31
- when "tcp"
32
- return TCPSocket.new uri.host, uri.port
33
- when "unix"
34
- path = "#{uri.host}#{uri.path}"
35
- return UNIXSocket.new path
36
- else
37
- raise "Invalid URI: #{str}"
29
+ o.on "-Q", "--quiet", "Not display messages" do |arg|
30
+ @options[:quiet_flag] = true
31
+ end
32
+
33
+ o.on "-P", "--pidfile PATH", "Pid file" do |arg|
34
+ @options[:pid_file] = arg
35
+ end
36
+
37
+ o.on "-p", "--pid PID", "Pid" do |arg|
38
+ @options[:pid] = arg.to_i
39
+ end
40
+
41
+ o.on "-C", "--control-url URL", "The bind url to use for the control server" do |arg|
42
+ @options[:control_url] = arg
43
+ end
44
+
45
+ o.on "-T", "--control-token TOKEN", "The token to use as authentication for the control server" do |arg|
46
+ @options[:control_auth_token] = arg
47
+ end
48
+
49
+ o.on_tail("-H", "--help", "Show this message") do
50
+ @stdout.puts o
51
+ exit
38
52
  end
53
+
54
+ o.on_tail("-V", "--version", "Show version") do
55
+ puts Const::PUMA_VERSION
56
+ exit
57
+ end
58
+ end
59
+
60
+ opts.order!(argv) { |a| opts.terminate a }
61
+
62
+ command = argv.shift
63
+ @options[:command] = command if command
64
+
65
+ # check present of command
66
+ unless @options[:command]
67
+ raise "Available commands: #{COMMANDS.join(", ")}"
68
+ end
69
+
70
+ unless COMMANDS.include? @options[:command]
71
+ raise "Invalid command: #{@options[:command]}"
39
72
  end
40
73
 
41
- raise "No status address configured"
74
+ rescue => e
75
+ @stdout.puts e.message
76
+ exit 1
77
+ end
78
+
79
+ def message(msg)
80
+ @stdout.puts msg unless @options[:quiet_flag]
42
81
  end
43
82
 
44
- def run
45
- setup_options
83
+ def prepare_configuration
84
+ if @options.has_key? :status_path
85
+ unless File.exist? @options[:status_path]
86
+ raise "Status file not found: #{@options[:status_path]}"
87
+ end
46
88
 
47
- @parser.parse! @argv
89
+ status = YAML.load File.read(@options[:status_path])
48
90
 
49
- @state = YAML.load File.read(@path)
50
- @config = @state['config']
91
+ if status.has_key? "config"
51
92
 
52
- cmd = @argv.shift
93
+ conf = status["config"]
53
94
 
54
- meth = "command_#{cmd}"
95
+ # get control_url
96
+ if url = conf.options[:control_url]
97
+ @options[:control_url] = url
98
+ end
55
99
 
56
- if respond_to?(meth)
57
- __send__(meth)
58
- else
59
- raise "Unknown command: #{cmd}"
100
+ # get control_auth_token
101
+ if token = conf.options[:control_auth_token]
102
+ @options[:control_auth_token] = token
103
+ end
104
+
105
+ # get pid
106
+ @options[:pid] = status["pid"].to_i
107
+ else
108
+ raise "Invalid status file: #{@options[:status_path]}"
109
+ end
110
+
111
+ elsif @options.has_key? :pid_file
112
+ # get pid from pid_file
113
+ @options[:pid] = File.open(@options[:pid_file]).gets.to_i
60
114
  end
61
115
  end
62
116
 
63
- def request(sock, url)
64
- token = @config.options[:control_auth_token]
65
- if token
66
- url = "#{url}?token=#{token}"
67
- end
117
+ def send_request
118
+ uri = URI.parse @options[:control_url]
119
+
120
+ # create server object by scheme
121
+ @server = case uri.scheme
122
+ when "tcp"
123
+ TCPSocket.new uri.host, uri.port
124
+ when "unix"
125
+ UNIXSocket.new "#{uri.host}#{uri.path}"
126
+ else
127
+ raise "Invalid scheme: #{uri.scheme}"
128
+ end
129
+
130
+ if @options[:command] == "status"
131
+ message "Puma is started"
132
+ else
133
+ url = "/#{@options[:command]}"
68
134
 
69
- sock << "GET #{url} HTTP/1.0\r\n\r\n"
135
+ if @options.has_key?(:control_auth_token)
136
+ url = url + "?token=#{@options[:control_auth_token]}"
137
+ end
70
138
 
71
- rep = sock.read.split("\r\n")
139
+ @server << "GET #{url} HTTP/1.0\r\n\r\n"
72
140
 
73
- m = %r!HTTP/1.\d (\d+)!.match(rep.first)
74
- if m[1] == "403"
75
- raise "Unauthorized access to server (wrong auth token)"
76
- elsif m[1] != "200"
77
- raise "Bad response code from server: #{m[1]}"
78
- end
141
+ response = @server.read.split("\r\n")
79
142
 
80
- return rep.last
81
- end
143
+ (@http,@code,@message) = response.first.split(" ")
144
+
145
+ if @code == "403"
146
+ raise "Unauthorized access to server (wrong auth token)"
147
+ elsif @code != "200"
148
+ raise "Bad response from server: #{@code}"
149
+ end
82
150
 
83
- def command_pid
84
- @stdout.puts "#{@state['pid']}"
151
+ message "Command #{@options[:command]} sent success"
152
+ end
153
+
154
+ @server.close
85
155
  end
86
156
 
87
- def command_stop
88
- sock = connect
89
- body = request sock, "/stop"
157
+ def send_signal
158
+ unless pid = @options[:pid]
159
+ raise "Neither pid nor control url available"
160
+ end
90
161
 
91
- if body != '{ "status": "ok" }'
92
- raise "Invalid response: '#{body}'"
93
- else
94
- @stdout.puts "Requested stop from server"
162
+ begin
163
+ Process.getpgid pid
164
+ rescue SystemCallError
165
+ raise "No pid '#{pid}' found"
95
166
  end
96
- end
97
167
 
98
- def command_halt
99
- sock = connect
100
- body = request sock, "/halt"
168
+ case @options[:command]
169
+ when "restart"
170
+ Process.kill "SIGUSR2", pid
171
+
172
+ when "halt"
173
+ Process.kill "QUIT", pid
174
+
175
+ when "stop"
176
+ Process.kill "SIGTERM", pid
177
+
178
+ when "stats"
179
+ puts "Stats not available via pid only"
180
+ return
101
181
 
102
- if body != '{ "status": "ok" }'
103
- raise "Invalid response: '#{body}'"
104
182
  else
105
- @stdout.puts "Requested halt from server"
183
+ message "Puma is started"
184
+ return
106
185
  end
186
+
187
+ message "Command #{@options[:command]} sent success"
107
188
  end
108
189
 
109
- def command_restart
110
- sock = connect
111
- body = request sock, "/restart"
190
+ def run
191
+ if @options[:command] == "start"
192
+ require 'puma/cli'
112
193
 
113
- if body != '{ "status": "ok" }'
114
- raise "Invalid response: '#{body}'"
115
- else
116
- @stdout.puts "Requested restart from server"
194
+ cli = Puma::CLI.new @argv, @stdout, @stderr
195
+ cli.run
196
+ return
117
197
  end
118
- end
119
198
 
120
- def command_stats
121
- sock = connect
122
- body = request sock, "/stats"
199
+ prepare_configuration
200
+
201
+ if is_windows?
202
+ send_request
203
+ else
204
+ @options.has_key?(:control_url) ? send_request : send_signal
205
+ end
123
206
 
124
- @stdout.puts body
207
+ rescue => e
208
+ message e.message
209
+ exit 1
125
210
  end
126
211
  end
127
- end
212
+ end
Binary file
Binary file
@@ -263,6 +263,8 @@ module Puma
263
263
  @events.unknown_error self, e, "Read"
264
264
 
265
265
  ensure
266
+ buffer.reset
267
+
266
268
  begin
267
269
  client.close if close_socket
268
270
  rescue IOError, SystemCallError
@@ -82,11 +82,6 @@ module Puma
82
82
  @waiting += 1
83
83
  cond.wait mutex
84
84
  @waiting -= 1
85
-
86
- if @shutdown
87
- continue = false
88
- break
89
- end
90
85
  end
91
86
 
92
87
  work = todo.pop if continue
@@ -58,3 +58,9 @@ module Rack
58
58
  register :puma, Puma
59
59
  end
60
60
  end
61
+
62
+ # This is to trick newrelic into enabling the agent automatically.
63
+ module Mongrel
64
+ class HttpServer
65
+ end
66
+ end
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "puma"
5
- s.version = "2.0.0.b1"
5
+ s.version = "2.0.0.b2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Phoenix"]
9
- s.date = "2012-09-12"
9
+ s.date = "2012-11-18"
10
10
  s.description = "Puma is a simple, fast, and highly concurrent HTTP 1.1 server for Ruby web applications. It can be used with any application that supports Rack, and is considered the replacement for Webrick and Mongrel. It was designed to be the go-to server for [Rubinius](http://rubini.us), but also works well with JRuby and MRI. Puma is intended for use in both development and production environments.\n\nUnder the hood, Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request in a thread from an internal thread pool (which you can control). This allows Puma to provide real concurrency for your web application!\n\nWith Rubinius 2.0, Puma will utilize all cores on your CPU with real threads, meaning you won't have to spawn multiple processes to increase throughput. You can expect to see a similar benefit from JRuby.\n\nOn MRI, there is a Global Interpreter Lock (GIL) that ensures only one thread can be run at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing blocking IO to be run concurrently (EventMachine-based servers such as Thin turn off this ability, requiring you to use special libraries). Your mileage may vary. In order to get the best throughput, it is highly recommended that you use a Ruby implementation with real threads like [Rubinius](http://rubini.us) or [JRuby](http://jruby.org)."
11
11
  s.email = ["evan@phx.io"]
12
12
  s.executables = ["puma", "pumactl"]
13
13
  s.extensions = ["ext/puma_http11/extconf.rb"]
14
14
  s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
15
- s.files = ["COPYING", "Gemfile", "Gemfile.lock", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "bin/pumactl", "examples/CA/cacert.pem", "examples/CA/newcerts/cert_1.pem", "examples/CA/newcerts/cert_2.pem", "examples/CA/private/cakeypair.pem", "examples/CA/serial", "examples/config.rb", "examples/puma/cert_puma.pem", "examples/puma/csr_puma.pem", "examples/puma/puma_keypair.pem", "examples/qc_config.rb", "ext/puma_http11/PumaHttp11Service.java", "ext/puma_http11/ext_help.h", "ext/puma_http11/extconf.rb", "ext/puma_http11/http11_parser.c", "ext/puma_http11/http11_parser.h", "ext/puma_http11/http11_parser.java.rl", "ext/puma_http11/http11_parser.rl", "ext/puma_http11/http11_parser_common.rl", "ext/puma_http11/org/jruby/puma/Http11.java", "ext/puma_http11/org/jruby/puma/Http11Parser.java", "ext/puma_http11/puma_http11.c", "lib/puma.rb", "lib/puma/app/status.rb", "lib/puma/cli.rb", "lib/puma/client.rb", "lib/puma/compat.rb", "lib/puma/configuration.rb", "lib/puma/const.rb", "lib/puma/control_cli.rb", "lib/puma/detect.rb", "lib/puma/events.rb", "lib/puma/jruby_restart.rb", "lib/puma/null_io.rb", "lib/puma/rack_patch.rb", "lib/puma/reactor.rb", "lib/puma/server.rb", "lib/puma/thread_pool.rb", "lib/rack/handler/puma.rb", "puma.gemspec", "test/ab_rs.rb", "test/config/app.rb", "test/hello-post.ru", "test/hello.ru", "test/lobster.ru", "test/mime.yaml", "test/slow.ru", "test/test_app_status.rb", "test/test_cli.rb", "test/test_config.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_integration.rb", "test/test_null_io.rb", "test/test_persistent.rb", "test/test_puma_server.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb", "test/testhelp.rb", "tools/trickletest.rb", "test/test_iobuffer.rb"]
15
+ s.files = ["COPYING", "Gemfile", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "bin/pumactl", "docs/config.md", "docs/nginx.md", "examples/CA/cacert.pem", "examples/CA/newcerts/cert_1.pem", "examples/CA/newcerts/cert_2.pem", "examples/CA/private/cakeypair.pem", "examples/CA/serial", "examples/config.rb", "examples/puma/cert_puma.pem", "examples/puma/csr_puma.pem", "examples/puma/keystore.jks", "examples/puma/puma_keypair.pem", "examples/qc_config.rb", "ext/puma_http11/PumaHttp11Service.java", "ext/puma_http11/ext_help.h", "ext/puma_http11/extconf.rb", "ext/puma_http11/http11_parser.c", "ext/puma_http11/http11_parser.h", "ext/puma_http11/http11_parser.java.rl", "ext/puma_http11/http11_parser.rl", "ext/puma_http11/http11_parser_common.rl", "ext/puma_http11/io_buffer.c", "ext/puma_http11/mini_ssl.c", "ext/puma_http11/org/jruby/puma/Http11.java", "ext/puma_http11/org/jruby/puma/Http11Parser.java", "ext/puma_http11/org/jruby/puma/MiniSSL.java", "ext/puma_http11/puma_http11.c", "lib/puma.rb", "lib/puma/accept_nonblock.rb", "lib/puma/app/status.rb", "lib/puma/binder.rb", "lib/puma/cli.rb", "lib/puma/client.rb", "lib/puma/compat.rb", "lib/puma/configuration.rb", "lib/puma/const.rb", "lib/puma/control_cli.rb", "lib/puma/delegation.rb", "lib/puma/detect.rb", "lib/puma/events.rb", "lib/puma/io_buffer.rb", "lib/puma/java_io_buffer.rb", "lib/puma/jruby_restart.rb", "lib/puma/minissl.rb", "lib/puma/null_io.rb", "lib/puma/puma_http11.bundle", "lib/puma/puma_http11.jar", "lib/puma/rack_patch.rb", "lib/puma/reactor.rb", "lib/puma/server.rb", "lib/puma/thread_pool.rb", "lib/rack/handler/puma.rb", "puma.gemspec", "test/ab_rs.rb", "test/config/app.rb", "test/hello-post.ru", "test/hello.ru", "test/lobster.ru", "test/mime.yaml", "test/slow.ru", "test/test_app_status.rb", "test/test_cli.rb", "test/test_config.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_integration.rb", "test/test_iobuffer.rb", "test/test_null_io.rb", "test/test_persistent.rb", "test/test_puma_server.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb", "test/testhelp.rb", "tools/jungle/README.md", "tools/jungle/puma", "tools/jungle/run-puma", "tools/trickletest.rb"]
16
16
  s.homepage = "http://puma.io"
17
17
  s.rdoc_options = ["--main", "README.md"]
18
18
  s.require_paths = ["lib"]
@@ -75,10 +75,14 @@ class TestAppStatus < Test::Unit::TestCase
75
75
  def test_stats
76
76
  @server.backlog = 1
77
77
  @server.running = 9
78
-
79
78
  status, _ , app = lint('/stats')
80
79
 
81
80
  assert_equal 200, status
82
81
  assert_equal ['{ "backlog": 1, "running": 9 }'], app.enum_for.to_a
83
82
  end
83
+
84
+ def test_alternate_location
85
+ status, _ , app = lint('__alternatE_location_/stats')
86
+ assert_equal 200, status
87
+ end
84
88
  end
@@ -85,7 +85,7 @@ class TestIntegration < Test::Unit::TestCase
85
85
  assert_kind_of Thread, t.join(1), "server didn't stop"
86
86
  end
87
87
 
88
- def test_restart_closes_keepalive_sockets
88
+ def notest_restart_closes_keepalive_sockets
89
89
  server("-q test/hello.ru")
90
90
 
91
91
  s = TCPSocket.new "localhost", @tcp_port
@@ -102,7 +102,7 @@ class TestIntegration < Test::Unit::TestCase
102
102
 
103
103
  assert_raises Errno::ECONNRESET do
104
104
  Timeout.timeout(2) do
105
- s.read(2)
105
+ raise Errno::ECONNRESET unless s.read(2)
106
106
  end
107
107
  end
108
108
 
@@ -111,7 +111,7 @@ class TestIntegration < Test::Unit::TestCase
111
111
  assert_equal "Hello World", s.read.split("\r\n").last
112
112
  end
113
113
 
114
- def test_restart_closes_keepalive_sockets_workers
114
+ def notest_restart_closes_keepalive_sockets_workers
115
115
  server("-q -w 2 test/hello.ru")
116
116
 
117
117
  s = TCPSocket.new "localhost", @tcp_port
@@ -128,7 +128,7 @@ class TestIntegration < Test::Unit::TestCase
128
128
 
129
129
  assert_raises Errno::ECONNRESET do
130
130
  Timeout.timeout(2) do
131
- s.read(2)
131
+ raise Errno::ECONNRESET unless s.read(2)
132
132
  end
133
133
  end
134
134
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.b1
4
+ version: 2.0.0.b2
5
5
  prerelease: 6
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: 2012-09-12 00:00:00.000000000 Z
12
+ date: 2012-11-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -113,7 +113,6 @@ extra_rdoc_files:
113
113
  files:
114
114
  - COPYING
115
115
  - Gemfile
116
- - Gemfile.lock
117
116
  - History.txt
118
117
  - LICENSE
119
118
  - Manifest.txt
@@ -1,27 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- bouncy-castle-java (1.5.0146.1)
5
- hoe (3.0.7)
6
- rake (~> 0.8)
7
- jruby-openssl (0.7.7)
8
- bouncy-castle-java (>= 1.5.0146.1)
9
- json (1.7.4)
10
- json (1.7.4-java)
11
- rack (1.4.1)
12
- rake (0.9.2.2)
13
- rake-compiler (0.8.1)
14
- rake
15
- rdoc (3.12)
16
- json (~> 1.4)
17
-
18
- PLATFORMS
19
- java
20
- ruby
21
-
22
- DEPENDENCIES
23
- hoe
24
- jruby-openssl
25
- rack
26
- rake-compiler
27
- rdoc