puma 2.4.1 → 2.5.0

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,25 @@
1
+ === 2.5.0 / 2013-08-08
2
+
3
+ * 2 minor features:
4
+ * Allow configuring pumactl with config.rb
5
+ * make `pumactl restart` start puma if not running
6
+
7
+ * 6 bug fixes:
8
+ * Autodetect ruby managers and home directory in upstart script
9
+ * Convert header values to string before sending.
10
+ * Correctly report phased-restart availability
11
+ * Fix pidfile creation/deletion race on jruby daemonization
12
+ * Use integers when comparing thread counts
13
+ * Fix typo in using lopez express (raw tcp) mode
14
+
15
+ * 6 misc changes:
16
+ * Fix typo in phased-restart response
17
+ * Uncomment setuid/setgid by default in upstart
18
+ * Use Puma::Const::PUMA_VERSION in gemspec
19
+ * Update upstart comments to reflect new commandline
20
+ * Remove obsolete pumactl instructions; refer to pumactl for details
21
+ * Make Bundler used puma.gemspec version agnostic
22
+
1
23
  === 2.4.1 / 2013-08-07
2
24
 
3
25
  * 1 experimental feature:
data/README.md CHANGED
@@ -180,17 +180,7 @@ Because of various platforms not being implement certain things, the following d
180
180
 
181
181
  ## pumactl
182
182
 
183
- 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:
184
-
185
- $ pumactl -S some/path command
186
-
187
- or
188
-
189
- $ pumactl -C url -T token command
190
-
191
- will cause the server to perform a restart. `pumactl` is a simple CLI frontend to the control/status app described above.
192
-
193
- Allowed commands: `status`, `restart`, `halt`, `stop`
183
+ `pumactl` is a simple CLI frontend to the control/status app described above. Please refer to `pumactl --help` for available commands.
194
184
 
195
185
  ## Managing multiple Pumas / init.d / upstart scripts
196
186
 
data/Rakefile CHANGED
@@ -75,16 +75,6 @@ task "changelog" do
75
75
  puts
76
76
  end
77
77
 
78
- # puma.gemspec
79
-
80
- file "#{HOE.spec.name}.gemspec" => ['Rakefile', "lib/puma/const.rb"] do |t|
81
- puts "Generating #{t.name}"
82
- File.open(t.name, 'wb') { |f| f.write HOE.spec.to_ruby }
83
- end
84
-
85
- desc "Generate or update the standalone gemspec file for the project"
86
- task :gemspec => ["#{HOE.spec.name}.gemspec"]
87
-
88
78
  # generate extension code using Ragel (C and Java)
89
79
  desc "Generate extension code (C and Java) using Ragel"
90
80
  task :ragel
@@ -43,7 +43,7 @@ module Puma
43
43
 
44
44
  when /\/phased-restart$/
45
45
  if !@cli.phased_restart
46
- return rack_response(404, '{ "error": "phased resart not available" }')
46
+ return rack_response(404, '{ "error": "phased restart not available" }')
47
47
  else
48
48
  return rack_response(200, OK_STATUS)
49
49
  end
@@ -503,8 +503,11 @@ module Puma
503
503
  end
504
504
 
505
505
  def phased_restart
506
- return restart unless @runner.respond_to? :phased_restart
507
- return restart unless @runner.phased_restart
506
+ unless @runner.respond_to?(:phased_restart) and @runner.phased_restart
507
+ log "* phased-restart called but not available, restarting normally."
508
+ return restart
509
+ end
510
+ true
508
511
  end
509
512
 
510
513
  def stats
@@ -266,8 +266,10 @@ module Puma
266
266
  # requests and +max+ the maximum.
267
267
  #
268
268
  def threads(min, max)
269
+ min = Integer(min)
270
+ max = Integer(max)
269
271
  if min > max
270
- raise "The minimum number of threads must be less than the max"
272
+ raise "The minimum (#{min}) number of threads must be less than the max (#{max})"
271
273
  end
272
274
 
273
275
  @options[:min_threads] = min
@@ -28,8 +28,8 @@ module Puma
28
28
  # too taxing on performance.
29
29
  module Const
30
30
 
31
- PUMA_VERSION = VERSION = "2.4.1".freeze
32
- CODE_NAME = "Crunchy Munchy Lunchy"
31
+ PUMA_VERSION = VERSION = "2.5.0".freeze
32
+ CODE_NAME = "Astronaut Shoelaces"
33
33
 
34
34
  FAST_TRACK_KA_TIMEOUT = 0.2
35
35
 
@@ -18,12 +18,12 @@ module Puma
18
18
  @stdout = stdout
19
19
  @stderr = stderr
20
20
  @options = {}
21
-
21
+
22
22
  opts = OptionParser.new do |o|
23
- o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token) (#{COMMANDS.join("|")})"
23
+ o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token | -F config.rb) (#{COMMANDS.join("|")})"
24
24
 
25
25
  o.on "-S", "--state PATH", "Where the state file to use is" do |arg|
26
- @options[:status_path] = arg
26
+ @options[:state] = arg
27
27
  end
28
28
 
29
29
  o.on "-Q", "--quiet", "Not display messages" do |arg|
@@ -31,7 +31,7 @@ module Puma
31
31
  end
32
32
 
33
33
  o.on "-P", "--pidfile PATH", "Pid file" do |arg|
34
- @options[:pid_file] = arg
34
+ @options[:pidfile] = arg
35
35
  end
36
36
 
37
37
  o.on "-p", "--pid PID", "Pid" do |arg|
@@ -46,6 +46,10 @@ module Puma
46
46
  @options[:control_auth_token] = arg
47
47
  end
48
48
 
49
+ o.on "-F", "--config-file PATH", "Puma config script" do |arg|
50
+ @options[:config_file] = arg
51
+ end
52
+
49
53
  o.on_tail("-H", "--help", "Show this message") do
50
54
  @stdout.puts o
51
55
  exit
@@ -58,35 +62,37 @@ module Puma
58
62
  end
59
63
 
60
64
  opts.order!(argv) { |a| opts.terminate a }
61
-
65
+
62
66
  command = argv.shift
63
67
  @options[:command] = command if command
64
68
 
69
+ Puma::Configuration.new(@options).load if @options[:config_file]
70
+
65
71
  # check present of command
66
72
  unless @options[:command]
67
73
  raise "Available commands: #{COMMANDS.join(", ")}"
68
74
  end
69
75
 
70
76
  unless COMMANDS.include? @options[:command]
71
- raise "Invalid command: #{@options[:command]}"
77
+ raise "Invalid command: #{@options[:command]}"
72
78
  end
73
79
 
74
80
  rescue => e
75
81
  @stdout.puts e.message
76
82
  exit 1
77
83
  end
78
-
84
+
79
85
  def message(msg)
80
86
  @stdout.puts msg unless @options[:quiet_flag]
81
87
  end
82
88
 
83
89
  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]}"
90
+ if @options.has_key? :state
91
+ unless File.exist? @options[:state]
92
+ raise "Status file not found: #{@options[:state]}"
87
93
  end
88
94
 
89
- status = YAML.load File.read(@options[:status_path])
95
+ status = YAML.load File.read(@options[:state])
90
96
 
91
97
  if status.kind_of?(Hash) && status.has_key?("config")
92
98
 
@@ -105,18 +111,18 @@ module Puma
105
111
  # get pid
106
112
  @options[:pid] = status["pid"].to_i
107
113
  else
108
- raise "Invalid status file: #{@options[:status_path]}"
114
+ raise "Invalid status file: #{@options[:state]}"
109
115
  end
110
116
 
111
- elsif @options.has_key? :pid_file
117
+ elsif @options.has_key? :pidfile
112
118
  # get pid from pid_file
113
- @options[:pid] = File.open(@options[:pid_file]).gets.to_i
119
+ @options[:pid] = File.open(@options[:pidfile]).gets.to_i
114
120
  end
115
121
  end
116
122
 
117
123
  def send_request
118
124
  uri = URI.parse @options[:control_url]
119
-
125
+
120
126
  # create server object by scheme
121
127
  @server = case uri.scheme
122
128
  when "tcp"
@@ -161,7 +167,7 @@ module Puma
161
167
  message "Command #{@options[:command]} sent success"
162
168
  message response.last if @options[:command] == "stats"
163
169
  end
164
-
170
+
165
171
  @server.close
166
172
  end
167
173
 
@@ -173,7 +179,12 @@ module Puma
173
179
  begin
174
180
  Process.getpgid pid
175
181
  rescue SystemCallError
176
- raise "No pid '#{pid}' found"
182
+ if @options[:command] == "restart"
183
+ @options.delete(:command)
184
+ start
185
+ else
186
+ raise "No pid '#{pid}' found"
187
+ end
177
188
  end
178
189
 
179
190
  case @options[:command]
@@ -202,23 +213,10 @@ module Puma
202
213
  end
203
214
 
204
215
  def run
205
- if @options[:command] == "start"
206
- require 'puma/cli'
207
-
208
- run_args = @argv
209
- if path = @options[:status_path]
210
- run_args = ["-S", path] + run_args
211
- end
212
-
213
- events = Puma::Events.new @stdout, @stderr
214
-
215
- cli = Puma::CLI.new run_args, events
216
- cli.run
217
- return
218
- end
216
+ start if @options[:command] == "start"
219
217
 
220
218
  prepare_configuration
221
-
219
+
222
220
  if is_windows?
223
221
  send_request
224
222
  else
@@ -229,5 +227,25 @@ module Puma
229
227
  message e.message
230
228
  exit 1
231
229
  end
230
+
231
+ private
232
+ def start
233
+ require 'puma/cli'
234
+
235
+ run_args = @argv
236
+
237
+ if path = @options[:state]
238
+ run_args = ["-S", path] + run_args
239
+ end
240
+
241
+ if path = @options[:config_file]
242
+ run_args = ["-C", path] + run_args
243
+ end
244
+
245
+ events = Puma::Events.new @stdout, @stderr
246
+
247
+ cli = Puma::CLI.new run_args, events
248
+ cli.run
249
+ end
232
250
  end
233
- end
251
+ end
@@ -160,7 +160,7 @@ module Puma
160
160
  @thread = Thread.new { handle_servers_lopez_mode }
161
161
  return @thread
162
162
  else
163
- handle_lopez_servers
163
+ handle_servers_lopez_mode
164
164
  end
165
165
  end
166
166
 
@@ -549,8 +549,12 @@ module Puma
549
549
  next
550
550
  end
551
551
 
552
- vs.split(NEWLINE).each do |v|
553
- lines.append k, colon, v, line_ending
552
+ if vs.respond_to?(:to_s)
553
+ vs.to_s.split(NEWLINE).each do |v|
554
+ lines.append k, colon, v, line_ending
555
+ end
556
+ else
557
+ lines.append k, colon, line_ending
554
558
  end
555
559
  end
556
560
 
@@ -52,7 +52,11 @@ module Puma
52
52
 
53
53
  Signal.trap "SIGUSR2" do
54
54
  log "* Started new process #{pid} as daemon..."
55
- exit
55
+
56
+ # Must use exit! so we don't unwind and run the ensures
57
+ # that will be run by the new child (such as deleting the
58
+ # pidfile)
59
+ exit!
56
60
  end
57
61
 
58
62
  Signal.trap "SIGCHLD" do
@@ -1,18 +1,20 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
+ # This is only used when puma is a git dep from Bundler, so it's a little
4
+ # weird.
5
+
3
6
  Gem::Specification.new do |s|
4
7
  s.name = "puma"
5
- s.version = "2.4.1"
8
+ s.version = Puma::Const::PUMA_VERSION
6
9
 
7
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
11
  s.authors = ["Evan Phoenix"]
9
- s.date = "2013-08-07"
12
+ s.date = `git log --pretty="%ai" -n 1`.split(" ").first
10
13
  s.description = "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications. Puma is intended for use in both development and production environments. In order to get the best throughput, it is highly recommended that you use a Ruby implementation with real threads like Rubinius or JRuby."
11
14
  s.email = ["evan@phx.io"]
12
15
  s.executables = ["puma", "pumactl"]
13
16
  s.extensions = ["ext/puma_http11/extconf.rb"]
14
- s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.md", "docs/config.md", "docs/nginx.md", "tools/jungle/README.md", "tools/jungle/init.d/README.md", "tools/jungle/upstart/README.md"]
15
- s.files = ["COPYING", "Gemfile", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "bin/pumactl", "docs/config.md", "docs/nginx.md", "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/capistrano.rb", "lib/puma/cli.rb", "lib/puma/client.rb", "lib/puma/cluster.rb", "lib/puma/compat.rb", "lib/puma/configuration.rb", "lib/puma/const.rb", "lib/puma/control_cli.rb", "lib/puma/daemon_ext.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/rack_default.rb", "lib/puma/rack_patch.rb", "lib/puma/reactor.rb", "lib/puma/runner.rb", "lib/puma/server.rb", "lib/puma/single.rb", "lib/puma/tcp_logger.rb", "lib/puma/thread_pool.rb", "lib/puma/util.rb", "lib/rack/handler/puma.rb", "puma.gemspec", "tools/jungle/README.md", "tools/jungle/init.d/README.md", "tools/jungle/init.d/puma", "tools/jungle/init.d/run-puma", "tools/jungle/upstart/README.md", "tools/jungle/upstart/puma-manager.conf", "tools/jungle/upstart/puma.conf", "tools/trickletest.rb", "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_minissl.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_tcp_rack.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
17
+ s.files = `git ls-files`.split($/)
16
18
  s.homepage = "http://puma.io"
17
19
  s.rdoc_options = ["--main", "README.md"]
18
20
  s.require_paths = ["lib"]
@@ -20,7 +22,7 @@ Gem::Specification.new do |s|
20
22
  s.rubyforge_project = "puma"
21
23
  s.rubygems_version = "1.8.25"
22
24
  s.summary = "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications"
23
- s.test_files = ["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_minissl.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_tcp_rack.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
25
+ s.test_files = s.files.grep(/^test/)
24
26
 
25
27
  if s.respond_to? :specification_version then
26
28
  s.specification_version = 3
@@ -7,9 +7,9 @@
7
7
  # See workers.conf for how to manage all Puma instances at once.
8
8
  #
9
9
  # Save this config as /etc/init/puma.conf then manage puma with:
10
- # sudo start puma index=0
11
- # sudo stop puma index=0
12
- # sudo status puma index=0
10
+ # sudo start puma app=PATH_TO_APP
11
+ # sudo stop puma app=PATH_TO_APP
12
+ # sudo status puma app=PATH_TO_APP
13
13
  #
14
14
  # or use the service command:
15
15
  # sudo service puma {start,stop,restart,status}
@@ -20,9 +20,9 @@ description "Puma Background Worker"
20
20
  # no "start on", we don't want to automatically start
21
21
  stop on (stopping puma-manager or runlevel [06])
22
22
 
23
- # change apps to match your deployment user if you want to use this as a less privileged user (recommended!)
24
- # setuid apps
25
- # setgid apps
23
+ # change apps to match your deployment user if you want to use this as a less privileged user (recommended!)
24
+ setuid apps
25
+ setgid apps
26
26
 
27
27
  respawn
28
28
  respawn limit 3 30
@@ -32,21 +32,33 @@ instance ${app}
32
32
  script
33
33
  # this script runs in /bin/sh by default
34
34
  # respawn as bash so we can source in rbenv/rvm
35
- exec /bin/bash <<EOT
36
- export HOME=/home/apps
37
-
38
- # Pick your poison :) Or none if you're using a system wide installed Ruby.
39
- # rbenv
40
- # source /home/apps/.bash_profile
41
- # OR
42
- # source /home/apps/.profile
43
- #
44
- # rvm
45
- # source /home/apps/.rvm/scripts/rvm
35
+ # quoted heredoc to tell /bin/sh not to interpret
36
+ # variables
37
+ exec /bin/bash <<'EOT'
38
+ # set HOME to the setuid user's home, there doesn't seem to be a better, portable way
39
+ export HOME="$(eval echo ~$(id -un))"
40
+
41
+ cd $app
42
+
43
+ if [ -d "$HOME/.rbenv/bin" ]; then
44
+ export PATH="$HOME/.rbenv/bin:$PATH"
45
+ elif [ -f /etc/profile.d/rvm.sh ]; then
46
+ source /etc/profile.d/rvm.sh
47
+ elif [ -f /usr/local/rvm/scripts/rvm ]; then
48
+ source /etc/profile.d/rvm.sh
49
+ elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
50
+ source "$HOME/.rvm/scripts/rvm"
51
+ elif [ -f /usr/local/share/chruby/chruby.sh ]; then
52
+ source /usr/local/share/chruby/chruby.sh
53
+ if [ -f /usr/local/share/chruby/auto.sh ]; then
54
+ source /usr/local/share/chruby/auto.sh
55
+ fi
56
+ # if you aren't using auto, set your version here
57
+ # chruby 2.0.0
58
+ fi
46
59
 
47
60
  logger -t puma "Starting server: $app"
48
61
 
49
- cd $app
50
- exec bundle exec puma -C config/puma.rb
62
+ exec bundle exec puma -C config/puma/production.rb
51
63
  EOT
52
- end script
64
+ end script
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.4.1
4
+ version: 2.5.0
5
5
  prerelease:
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-08-07 00:00:00.000000000 Z
12
+ date: 2013-08-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack