puma 2.14.0 → 2.15.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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1906e2cec23c83e7ed5a2e8fb54885809c8bfa1
4
- data.tar.gz: 8cd1fb3dc9caeb4fe4aa4be995e746beebdaa4d0
3
+ metadata.gz: ac9ff84e4c17a8e7e00a82e37d94da488e96f640
4
+ data.tar.gz: e743d6fc5e07c6013facbd4d9b7ec917eb0e3fa4
5
5
  SHA512:
6
- metadata.gz: 74e867dea23de7b4743d810a29925eba7fbb2d4f674e7c9035985699dc35712d80591ea0b3b25a48b72d550f2550c42303719438c65b341e7b4d649af82b07ca
7
- data.tar.gz: aa8af24acdcda63f9a8ebfe2ebc573dd048f6e408954125144cf424abfc990baa451b8f6c7197ed015ff30ed2b6d110d96b9c34f67312d8076726b0c278d1c5b
6
+ metadata.gz: d6b09c19aea4d08df086befeef93a43836838e7375ff644756865e90c4d8a3b641be83209a942bd188d6e7d12ab4ffbd9d6ef02a04e954fcfdc7612d93ef1c8d
7
+ data.tar.gz: 7a39fbf08255d2379b59b8fece81374f8ce8026e5263863a523eb7a9a9d9caf6e10d667e818fab9705f1b271d99e7befcd63cca4f3788709388b4459b9da613f
@@ -1,7 +1,7 @@
1
1
  # Deployment engineering for puma
2
2
 
3
3
  Puma is software that is expected to be run in a deployed environment eventually.
4
- You can centainly use it as your dev server only, but most people look to use
4
+ You can certainly use it as your dev server only, but most people look to use
5
5
  it in their production deployments as well.
6
6
 
7
7
  To that end, this is meant to serve as a foundation of wisdom how to do that
@@ -17,7 +17,7 @@ Welcome back!
17
17
 
18
18
  ## Single vs Cluster mode
19
19
 
20
- Puma was originally concieved as a thread-only webserver, but grew the ability to
20
+ Puma was originally conceived as a thread-only webserver, but grew the ability to
21
21
  also use processes in version 2.
22
22
 
23
23
  Here are some rules of thumb:
@@ -27,7 +27,7 @@ Here are some rules of thumb:
27
27
  * Use cluster mode and set the number of workers to 1.5x the number of cpu cores
28
28
  in the machine, minimum 2.
29
29
  * Set the number of threads to desired concurrent requests / number of workers.
30
- Puma defaults to 8 and thats a decent number.
30
+ Puma defaults to 8 and that's a decent number.
31
31
 
32
32
  #### Migrating from Unicorn
33
33
 
@@ -1,3 +1,52 @@
1
+ === 2.15.0 / 2015-11-06
2
+
3
+ * 6 minor features:
4
+ * Allow setting ca without setting a verify mode
5
+ * Make jungle for init.d support rbenv
6
+ * Use SSL_CTX_use_certificate_chain_file for full chain
7
+ * cluster: add worker_boot_timeout option
8
+ * configuration: allow empty tags to mean no tag desired
9
+ * puma/cli: support specifying STD{OUT,ERR} redirections and append mode
10
+
11
+ * 5 bug fixes:
12
+ * Disable SSL Compression
13
+ * Fix bug setting worker_directory when using a symlink directory
14
+ * Fix error message in DSL that was slightly inaccurate
15
+ * Pumactl: set correct process name. Fixes #563
16
+ * thread_pool: fix race condition when shutting down workers
17
+
18
+ * 10 doc fixes:
19
+ * Add before_fork explanation in Readme.md
20
+ * Correct spelling in DEPLOYMENT.md
21
+ * Correct spelling in docs/nginx.md
22
+ * Fix spelling errors.
23
+ * Fix typo in deployment description
24
+ * Fix typos (it's -> its) in events.rb and server.rb
25
+ * fixing for typo mentioned in #803
26
+ * Spelling correction for README
27
+ * thread_pool: fix typos in comment
28
+ * More explicit docs for worker_timeout
29
+
30
+ * 18 PRs merged:
31
+ * Merge pull request #768 from nathansamson/patch-1
32
+ * Merge pull request #773 from rossta/spelling_corrections
33
+ * Merge pull request #774 from snow/master
34
+ * Merge pull request #781 from sunsations/fix-typo
35
+ * Merge pull request #791 from unleashed/allow_empty_tags
36
+ * Merge pull request #793 from robdimarco/fix-working-directory-symlink-bug
37
+ * Merge pull request #794 from peterkeen/patch-1
38
+ * Merge pull request #795 from unleashed/redirects-from-cmdline
39
+ * Merge pull request #796 from cschneid/fix_dsl_message
40
+ * Merge pull request #799 from annafw/master
41
+ * Merge pull request #800 from liamseanbrady/fix_typo
42
+ * Merge pull request #801 from scottjg/ssl-chain-file
43
+ * Merge pull request #802 from scottjg/ssl-crimes
44
+ * Merge pull request #804 from burningTyger/patch-2
45
+ * Merge pull request #809 from unleashed/threadpool-fix-race-in-shutdown
46
+ * Merge pull request #810 from vlmonk/fix-pumactl-restart-bug
47
+ * Merge pull request #814 from schneems/schneems/worker_timeout-docs
48
+ * Merge pull request #817 from unleashed/worker-boot-timeout
49
+
1
50
  === 2.14.0 / 2015-09-18
2
51
 
3
52
  * 1 minor feature:
data/README.md CHANGED
@@ -117,6 +117,25 @@ If you're preloading your application and using ActiveRecord, it's recommend you
117
117
  end
118
118
  end
119
119
 
120
+ On top of that, you can specify a block in your configuration file that will be run before workers are forked
121
+
122
+ # config/puma.rb
123
+ before_fork do
124
+ # configuration here
125
+ end
126
+
127
+ This code can be used to clean up before forking to clients, allowing
128
+ you to do some Puma-specific things that you don't want to embed in your application.
129
+
130
+ If you're preloading your application and using ActiveRecord, it's recommend you close any connections to the database here to prevent connection leakage:
131
+
132
+ # config/puma.rb
133
+ before_fork do
134
+ ActiveRecord::Base.connection_pool.disconnect!
135
+ end
136
+
137
+ This rule applies to any connections to external services (Redis, databases, memcache, ...) that might be started automatically by the framework.
138
+
120
139
  When you use preload_app, your new code goes all in the master process, and is then copied in the workers (meaning it’s only compatible with cluster mode). General rule is to use preload_app when your workers die often and need fast starts. If you don’t have many workers, you probably should not use preload_app.
121
140
 
122
141
  Note that preload_app can’t be used with phased restart, since phased restart kills and restarts workers one-by-one, and preload_app is all about copying the code of master into the workers.
@@ -167,7 +186,7 @@ You can also provide a configuration file which Puma will use with the `-C` (or
167
186
 
168
187
  $ puma -C /path/to/config
169
188
 
170
- By default, if no configuration file is specifed, Puma will look for a configuration file at config/puma.rb. If an environment is specified, either via the `-e` and `--environment` flags, or through the `RACK_ENV` environment variable, the default file location will be config/puma/environment_name.rb.
189
+ By default, if no configuration file is specified, Puma will look for a configuration file at config/puma.rb. If an environment is specified, either via the `-e` and `--environment` flags, or through the `RACK_ENV` environment variable, the default file location will be config/puma/environment_name.rb.
171
190
 
172
191
  If you want to prevent Puma from looking for a configuration file in those locations, provide a dash as the argument to the `-C` (or `--config`) flag:
173
192
 
@@ -40,7 +40,7 @@ server {
40
40
  }
41
41
 
42
42
  # check for index.html for directory index
43
- # if its there on the filesystem then rewite
43
+ # if it's there on the filesystem then rewrite
44
44
  # the url to add /index.html to the end of it
45
45
  # and then break to send it to the next config rules.
46
46
  if (-f $request_filename/index.html) {
@@ -136,14 +136,14 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
136
136
  ctx = SSL_CTX_new(SSLv23_server_method());
137
137
  conn->ctx = ctx;
138
138
 
139
- SSL_CTX_use_certificate_file(ctx, RSTRING_PTR(cert), SSL_FILETYPE_PEM);
139
+ SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
140
140
  SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
141
141
 
142
142
  if (!NIL_P(ca)) {
143
143
  SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
144
144
  }
145
145
 
146
- SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE);
146
+ SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION);
147
147
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
148
148
 
149
149
  SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
@@ -164,8 +164,9 @@ module Puma
164
164
  unless params['ca']
165
165
  @events.error "Please specify the SSL ca via 'ca='"
166
166
  end
167
- ctx.ca = params['ca']
168
167
  end
168
+
169
+ ctx.ca = params['ca']
169
170
 
170
171
  if params['verify_mode']
171
172
  ctx.verify_mode = case params['verify_mode']
@@ -266,7 +266,7 @@ module Puma
266
266
  private
267
267
  def title
268
268
  buffer = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})"
269
- buffer << " [#{@options[:tag]}]" if @options[:tag]
269
+ buffer << " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
270
270
  buffer
271
271
  end
272
272
 
@@ -410,6 +410,18 @@ module Puma
410
410
  @cli_options[:tag] = arg
411
411
  end
412
412
 
413
+ o.on "--redirect-stdout FILE", "Redirect STDOUT to a specific file" do |arg|
414
+ @cli_options[:redirect_stdout] = arg
415
+ end
416
+
417
+ o.on "--redirect-stderr FILE", "Redirect STDERR to a specific file" do |arg|
418
+ @cli_options[:redirect_stderr] = arg
419
+ end
420
+
421
+ o.on "--[no-]redirect-append", "Append to redirected files" do |val|
422
+ @cli_options[:redirect_append] = val
423
+ end
424
+
413
425
  o.banner = "puma <options> <rackup file>"
414
426
 
415
427
  o.on_tail "-h", "--help", "Show help" do
@@ -429,7 +441,7 @@ module Puma
429
441
 
430
442
  if s_env.ino == s_pwd.ino and (jruby? or s_env.dev == s_pwd.dev)
431
443
  @restart_dir = dir
432
- @cli_options[:worker_directory] = dir
444
+ @options[:worker_directory] = dir
433
445
  end
434
446
  end
435
447
 
@@ -136,6 +136,7 @@ module Puma
136
136
  any = false
137
137
 
138
138
  @workers.each do |w|
139
+ next if !w.booted? && !w.ping_timeout?(@options[:worker_boot_timeout])
139
140
  if w.ping_timeout?(@options[:worker_timeout])
140
141
  log "! Terminating timed out worker: #{w.pid}"
141
142
  w.kill
@@ -186,7 +187,7 @@ module Puma
186
187
 
187
188
  def worker(index, master)
188
189
  title = "puma: cluster worker #{index}: #{master}"
189
- title << " [#{@options[:tag]}]" if @options[:tag]
190
+ title << " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
190
191
  $0 = title
191
192
 
192
193
  Signal.trap "SIGINT", "IGNORE"
@@ -221,7 +222,7 @@ module Puma
221
222
  begin
222
223
  @worker_write << "b#{Process.pid}\n"
223
224
  rescue SystemCallError, IOError
224
- STDERR.puts "Master seems to have exitted, exitting."
225
+ STDERR.puts "Master seems to have exited, exiting."
225
226
  return
226
227
  end
227
228
 
@@ -27,6 +27,7 @@ module Puma
27
27
  @conf[:before_worker_fork] ||= []
28
28
  @conf[:after_worker_boot] ||= []
29
29
  @conf[:worker_timeout] ||= DefaultWorkerTimeout
30
+ @conf[:worker_boot_timeout] ||= @conf[:worker_timeout]
30
31
  @conf[:worker_shutdown_timeout] ||= DefaultWorkerShutdownTimeout
31
32
 
32
33
  @options = {}
@@ -99,8 +99,8 @@ module Puma
99
99
  # too taxing on performance.
100
100
  module Const
101
101
 
102
- PUMA_VERSION = VERSION = "2.14.0".freeze
103
- CODE_NAME = "Fuchsia Friday".freeze
102
+ PUMA_VERSION = VERSION = "2.15.0".freeze
103
+ CODE_NAME = "Autumn Arbor Airbrush".freeze
104
104
 
105
105
  FAST_TRACK_KA_TIMEOUT = 0.2
106
106
 
@@ -262,6 +262,10 @@ module Puma
262
262
 
263
263
  events = Puma::Events.new @stdout, @stderr
264
264
 
265
+ # replace $0 because puma use it to generate restart command
266
+ puma_cmd = $0.gsub(/pumactl$/, 'puma')
267
+ $0 = puma_cmd if File.exist?(puma_cmd)
268
+
265
269
  cli = Puma::CLI.new run_args, events
266
270
  cli.run
267
271
  end
@@ -132,7 +132,7 @@ module Puma
132
132
  min = Integer(min)
133
133
  max = Integer(max)
134
134
  if min > max
135
- raise "The minimum (#{min}) number of threads must be less than the max (#{max})"
135
+ raise "The minimum (#{min}) number of threads must be less than or equal to the max (#{max})"
136
136
  end
137
137
 
138
138
  @options[:min_threads] = min
@@ -256,11 +256,19 @@ module Puma
256
256
  @options[:tag] = string
257
257
  end
258
258
 
259
- # *Cluster mode only* Set the timeout for workers
259
+ # *Cluster mode only* Set the timeout for workers in seconds
260
+ # When set the master process will terminate any workers
261
+ # that have not checked in within the given +timeout+.
262
+ # This mitigates hung processes. Default value is 60 seconds.
260
263
  def worker_timeout(timeout)
261
264
  @options[:worker_timeout] = timeout
262
265
  end
263
266
 
267
+ # *Cluster mode only* Set the timeout for workers to boot
268
+ def worker_boot_timeout(timeout)
269
+ @options[:worker_boot_timeout] = timeout
270
+ end
271
+
264
272
  # *Cluster mode only* Set the timeout for worker shutdown
265
273
  def worker_shutdown_timeout(timeout)
266
274
  @options[:worker_shutdown_timeout] = timeout
@@ -128,7 +128,7 @@ module Puma
128
128
 
129
129
  DEFAULT = new(STDOUT, STDERR)
130
130
 
131
- # Returns an Events object which writes it's status to 2 StringIO
131
+ # Returns an Events object which writes its status to 2 StringIO
132
132
  # objects.
133
133
  #
134
134
  def self.strings
@@ -45,7 +45,7 @@ module Puma
45
45
  # to be handled. See Puma::Events for the list of current methods to implement.
46
46
  #
47
47
  # Server#run returns a thread that you can join on to wait for the server
48
- # to do it's work.
48
+ # to do its work.
49
49
  #
50
50
  def initialize(app, events=Events.stdio, options={})
51
51
  @app = app
@@ -62,7 +62,7 @@ module Puma
62
62
  end
63
63
 
64
64
  Signal.trap "SIGCHLD" do
65
- log "! Error starting new process as daemon, exitting"
65
+ log "! Error starting new process as daemon, exiting"
66
66
  exit 1
67
67
  end
68
68
 
@@ -160,7 +160,7 @@ module Puma
160
160
  end
161
161
 
162
162
  # If there are dead threads in the pool make them go away while decreasing
163
- # spwaned counter so that new healty threads could be created again.
163
+ # spawned counter so that new healthy threads could be created again.
164
164
  def reap
165
165
  @mutex.synchronize do
166
166
  dead_workers = @workers.reject(&:alive?)
@@ -235,20 +235,18 @@ module Puma
235
235
  # Tell all threads in the pool to exit and wait for them to finish.
236
236
  #
237
237
  def shutdown
238
- @mutex.synchronize do
238
+ threads = @mutex.synchronize do
239
239
  @shutdown = true
240
240
  @not_empty.broadcast
241
241
  @not_full.broadcast
242
242
 
243
243
  @auto_trim.stop if @auto_trim
244
244
  @reaper.stop if @reaper
245
+ # dup workers so that we join them all safely
246
+ @workers.dup
245
247
  end
246
248
 
247
- # Use this instead of #each so that we don't stop in the middle
248
- # of each and see a mutated object mid #each
249
- if !@workers.empty?
250
- @workers.first.join until @workers.empty?
251
- end
249
+ threads.each(&:join)
252
250
 
253
251
  @spawned = 0
254
252
  @workers = []
@@ -50,7 +50,7 @@ module Rack
50
50
  "Host=HOST" => "Hostname to listen on (default: localhost)",
51
51
  "Port=PORT" => "Port to listen on (default: 8080)",
52
52
  "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
53
- "Quiet" => "Don't report each request"
53
+ "Verbose" => "Don't report each request (default: false)"
54
54
  }
55
55
  end
56
56
  end
@@ -23,6 +23,7 @@ SCRIPTNAME=/etc/init.d/$NAME
23
23
  CONFIG=/etc/puma.conf
24
24
  JUNGLE=`cat $CONFIG`
25
25
  RUNPUMA=/usr/local/bin/run-puma
26
+ USE_LOCAL_BUNDLE=0
26
27
 
27
28
  # Load the VERBOSE setting and other rcS variables
28
29
  . /lib/init/vars.sh
@@ -105,7 +106,11 @@ do_stop_one() {
105
106
  log_daemon_msg "---> Puma $1 isn't running."
106
107
  else
107
108
  log_daemon_msg "---> About to kill PID `cat $PIDFILE`"
108
- pumactl --state $STATEFILE stop
109
+ if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
110
+ cd $1 && bundle exec pumactl --state $STATEFILE stop
111
+ else
112
+ pumactl --state $STATEFILE stop
113
+ fi
109
114
  # Many daemons don't delete their pidfiles when they exit.
110
115
  rm -f $PIDFILE $STATEFILE
111
116
  fi
@@ -135,7 +140,11 @@ do_restart_one() {
135
140
 
136
141
  if [ -e $PIDFILE ]; then
137
142
  log_daemon_msg "--> About to restart puma $1"
138
- pumactl --state $dir/tmp/puma/state restart
143
+ if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
144
+ cd $1 && bundle exec pumactl --state $dir/tmp/puma/state restart
145
+ else
146
+ pumactl --state $dir/tmp/puma/state restart
147
+ fi
139
148
  # kill -s USR2 `cat $PIDFILE`
140
149
  # TODO Check if process exist
141
150
  else
@@ -175,7 +184,11 @@ do_status_one() {
175
184
 
176
185
  if [ -e $PIDFILE ]; then
177
186
  log_daemon_msg "--> About to status puma $1"
178
- pumactl --state $dir/tmp/puma/state stats
187
+ if [ "$USE_LOCAL_BUNDLE" -eq 1 ]; then
188
+ cd $1 && bundle exec pumactl --state $dir/tmp/puma/state stats
189
+ else
190
+ pumactl --state $dir/tmp/puma/state stats
191
+ fi
179
192
  # kill -s USR2 `cat $PIDFILE`
180
193
  # TODO Check if process exist
181
194
  else
@@ -241,6 +254,40 @@ do_remove() {
241
254
  fi
242
255
  }
243
256
 
257
+ config_bundler() {
258
+ HOME="$(eval echo ~$(id -un))"
259
+ if [ -d "/usr/local/rbenv/bin" ]; then
260
+ PATH="/usr/local/rbenv/bin:/usr/local/rbenv/shims:$PATH"
261
+ eval "$(rbenv init -)"
262
+ USE_LOCAL_BUNDLE=1
263
+ return 0
264
+ elif [ -d "$HOME/.rbenv/bin" ]; then
265
+ PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
266
+ eval "$(rbenv init -)"
267
+ USE_LOCAL_BUNDLE=1
268
+ return 0
269
+ # TODO: test rvm
270
+ # elif [ -f /etc/profile.d/rvm.sh ]; then
271
+ # source /etc/profile.d/rvm.sh
272
+ # elif [ -f /usr/local/rvm/scripts/rvm ]; then
273
+ # source /etc/profile.d/rvm.sh
274
+ # elif [ -f "$HOME/.rvm/scripts/rvm" ]; then
275
+ # source "$HOME/.rvm/scripts/rvm"
276
+ # TODO: don't know what to do with chruby
277
+ # elif [ -f /usr/local/share/chruby/chruby.sh ]; then
278
+ # source /usr/local/share/chruby/chruby.sh
279
+ # if [ -f /usr/local/share/chruby/auto.sh ]; then
280
+ # source /usr/local/share/chruby/auto.sh
281
+ # fi
282
+ # if you aren't using auto, set your version here
283
+ # chruby 2.0.0
284
+ fi
285
+
286
+ return 1
287
+ }
288
+
289
+ config_bundler
290
+
244
291
  case "$1" in
245
292
  start)
246
293
  [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.14.0
4
+ version: 2.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-18 00:00:00.000000000 Z
11
+ date: 2015-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc