puma 2.8.0 → 2.8.1

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: 898a1954d5ebcc2e339fa1b455a0f772922550d9
4
- data.tar.gz: ed25f3dcea9438077229cfbfc9e4feca966a1190
3
+ metadata.gz: 74aab6aaab377487d53393978bbb59ffae181f66
4
+ data.tar.gz: 383b6735116a87480a5c73403107de1941da3e99
5
5
  SHA512:
6
- metadata.gz: 81e27d75599ba7fe68b342c375ba5bf1f80f8e6859072950ea20beb3de14a5c9c18272231c3d66734bab76622a258489a8e9bad6c8bedaaf7aae67e22dcfd980
7
- data.tar.gz: 17251b4e6c9af4e7af501e3974e7c42e836ac95798793e8b05df01cdb19cd8d9178ed960b84adb2030fb475d584fb0dee6fc01ff07e0ae5be40dd98199dba079
6
+ metadata.gz: 2d9663eec2cf39f8e7471937887633cb56a6b8a8989ab3055a8c64497637decc45b56b9d87d2873004ee56665ba9d8386da28c1dd9d216ff9c15942a5961a1e5
7
+ data.tar.gz: e65857e59cda95b3980761ec5bf8b00f55c55fa1798d6dc43c56c775e84872f7d36d28a5260c232c360f354d4fe865fcc9a76e731b1430e7f26d6291066c60fd
@@ -0,0 +1,92 @@
1
+ # Deployment engineering for puma
2
+
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
5
+ it in their production deployments as well.
6
+
7
+ To that end, this is meant to serve as a foundation of wisdom how to do that
8
+ in a way that increases happiness and decreases downtime.
9
+
10
+ ## Specifying puma
11
+
12
+ Most people want to do this by putting `gem "puma"` into their Gemfile, so we'll
13
+ go ahead and assume that. Go add it now... we'll wait.
14
+
15
+
16
+ Welcome back!
17
+
18
+ ## Single vs Cluster mode
19
+
20
+ Puma was originally concieved as a thread-only webserver, but grew the ability to
21
+ also use processes in version 2.
22
+
23
+ Here are some rules of thumb:
24
+
25
+ ### MRI
26
+
27
+ * Use cluster mode and set the number of workers to 1.5x the number of cpu cores
28
+ in the machine, minimum 2.
29
+ * Set the number of threads to desired concurrent requests / number of workers.
30
+ Puma defaults to 8 and thats a decent number.
31
+
32
+ #### Migrating from Unicorn
33
+
34
+ * If you're migrating from unicorn though, here are some settings to start with:
35
+ * Set workers to half the number of unicorn workers you're using
36
+ * Set threads to 2
37
+ * Enjoy 50% memory savings
38
+ * As you grow more confident in the thread safety of your app, you can tune the
39
+ workers down and the threads up.
40
+
41
+ #### Worker utilization
42
+
43
+ **How do you know if you're got enough (or too many workers)?**
44
+
45
+ A good question. Due to MRI's GIL, only one thread can be executing at a time.
46
+ But since so many apps are waiting on IO from DBs, etc., they can utilize threads
47
+ to make better use of the process.
48
+
49
+ The rule of thumb is you never want processes that are pegged all the time. This
50
+ means that there is more work to do that the process can get through. On the other
51
+ hand, if you have processes that sit around doing nothing, then they're just eating
52
+ up resources.
53
+
54
+ Watching your CPU utilization over time and aim for about 70% on average. This means
55
+ you've got capacity still but aren't starving threads.
56
+
57
+ ## Daemonizing
58
+
59
+ I prefer to not daemonize my servers and use something like `runit` or `upstrart` to
60
+ monitor them as child processes. This gives them fast response to crashes and
61
+ makes it easy to figure out what is going on. Additionally, unlike `unicorn`,
62
+ puma does not require daemonization to do zero-downtime restarts.
63
+
64
+ I see people using daemonization because they start puma directly via capistrano
65
+ task and thus want it to live on past the `cap deploy`. To this people I said:
66
+ You need to be using a process monitor. Nothing is making sure puma stays up in
67
+ this scenario! You're just waiting for something weird to happen, puma to die,
68
+ and to get paged at 3am. Do yourself a favor, at least the process monitoring
69
+ your OS comes with, be it `sysvinit`, `upstart`, or `systemd`. Or branch out
70
+ and use `runit` or hell, even `monit`.
71
+
72
+ ## Restarting
73
+
74
+ You probably will want to deploy some new code at some point, and you'd like
75
+ puma to start running that new code. Minimizing the amount of time the server
76
+ is unavailable would be nice as well. Here's how to do it:
77
+
78
+ 1. Don't use `preload!`. This dirties the master process and means it will have
79
+ to shutdown all the workers and re-exec itself to get your new code, which means
80
+ much higher waiting around for things to load.
81
+
82
+ 1. Use `prune_bundler`. This makes it so that the cluster master will detach itself
83
+ from a Bundler context on start. This allows the cluster workers to load your app
84
+ and start a brand new Bundler context within the worker only. This means your
85
+ master remains pristine and can live on between new releases of your code.
86
+
87
+ 1. Use phased-restart (`SIGUSR1` or `pumactl phased-restart`). This tells the master
88
+ to kill off one worker at a time and restart them in your new code. This minimizes
89
+ downtime and staggers the restart nicely. **WARNING** This means that both your
90
+ old code and your new code will be running concurrently. Most deployment solutions
91
+ already cause that, but it's worth warning you about it again. Be careful with your
92
+ migrations, etc!
@@ -1,3 +1,19 @@
1
+ === 2.8.1 / 2014-03-06
2
+
3
+ * 1 bug fixes:
4
+ * Run puma-wild with proper deps for prune_bundler
5
+
6
+ * 2 doc changes:
7
+ * Described the configuration file finding behavior added in 2.8.0 and how to disable it.
8
+ * Start the deployment doc
9
+
10
+ * 6 PRs merged:
11
+ * Merge pull request #471 from arthurnn/fix_test
12
+ * Merge pull request #485 from joneslee85/patch-9
13
+ * Merge pull request #486 from joshwlewis/patch-1
14
+ * Merge pull request #490 from tobinibot/patch-1
15
+ * Merge pull request #491 from brianknight10/clarify-no-config
16
+
1
17
  === 2.8.0 / 2014-02-28
2
18
 
3
19
  * 8 minor features:
@@ -1,4 +1,5 @@
1
1
  COPYING
2
+ DEPLOYMENT.md
2
3
  Gemfile
3
4
  History.txt
4
5
  LICENSE
@@ -6,6 +7,7 @@ Manifest.txt
6
7
  README.md
7
8
  Rakefile
8
9
  bin/puma
10
+ bin/puma-wild
9
11
  bin/pumactl
10
12
  docs/config.md
11
13
  docs/nginx.md
data/README.md CHANGED
@@ -149,6 +149,12 @@ You can also provide a configuration file which Puma will use with the `-C` (or
149
149
 
150
150
  $ puma -C /path/to/config
151
151
 
152
+ 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.
153
+
154
+ 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:
155
+
156
+ $ puma -C "-"
157
+
152
158
  Take the following [sample configuration](https://github.com/puma/puma/blob/master/examples/config.rb) as inspiration or check out [configuration.rb](https://github.com/puma/puma/blob/master/lib/puma/configuration.rb) to see all available options.
153
159
 
154
160
  ## Restart
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (c) 2014 Evan Phoenix
4
+ #
5
+
6
+ require 'rubygems'
7
+
8
+ deps = ARGV.shift.split(",").each do |s|
9
+ name, ver = s.split(":",2)
10
+ gem name, ver
11
+ end
12
+
13
+ require 'puma/cli'
14
+
15
+ cli = Puma::CLI.new ARGV
16
+
17
+ cli.run
@@ -456,14 +456,27 @@ module Puma
456
456
  end
457
457
 
458
458
  if prune_bundler? && defined?(Bundler)
459
- puma_lib_dir = $:.detect { |d| File.exist? File.join(d, "puma", "const.rb") }
459
+ puma = Bundler.rubygems.loaded_specs("puma")
460
+
461
+ dirs = puma.require_paths.map { |x| File.join(puma.full_gem_path, x) }
462
+
463
+ puma_lib_dir = dirs.detect { |x| File.exist? File.join(x, "../bin/puma-wild") }
464
+
465
+ deps = puma.runtime_dependencies.map { |d|
466
+ spec = Bundler.rubygems.loaded_specs(d.name)
467
+ "#{d.name}:#{spec.version.to_s}"
468
+ }.join(",")
460
469
 
461
470
  if puma_lib_dir
462
471
  log "* Pruning Bundler environment"
463
472
  Bundler.with_clean_env do
464
- Kernel.exec(Gem.ruby, "-I", puma_lib_dir,
465
- File.expand_path(puma_lib_dir + "/../bin/puma"),
466
- *@original_argv)
473
+
474
+ wild = File.expand_path(File.join(puma_lib_dir, "../bin/puma-wild"))
475
+
476
+ args = [Gem.ruby] + dirs.map { |x| ["-I", x] }.flatten +
477
+ [wild, deps] + @original_argv
478
+
479
+ Kernel.exec(*args)
467
480
  end
468
481
  end
469
482
 
@@ -28,8 +28,8 @@ module Puma
28
28
  # too taxing on performance.
29
29
  module Const
30
30
 
31
- PUMA_VERSION = VERSION = "2.8.0".freeze
32
- CODE_NAME = "Sir Edmund Percival Hillary"
31
+ PUMA_VERSION = VERSION = "2.8.1".freeze
32
+ CODE_NAME = "Sir Edmund Percival Hillary".freeze
33
33
 
34
34
  FAST_TRACK_KA_TIMEOUT = 0.2
35
35
 
@@ -58,7 +58,7 @@ module Puma
58
58
  PUMA_TMP_BASE = "puma".freeze
59
59
 
60
60
  # Indicate that we couldn't parse the request
61
- ERROR_400_RESPONSE = "HTTP/1.1 400 Bad Request\r\n\r\n"
61
+ ERROR_400_RESPONSE = "HTTP/1.1 400 Bad Request\r\n\r\n".freeze
62
62
 
63
63
  # The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
64
64
  ERROR_404_RESPONSE = "HTTP/1.1 404 Not Found\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\nNOT FOUND".freeze
@@ -69,7 +69,7 @@ module Puma
69
69
  CONTENT_LENGTH = "CONTENT_LENGTH".freeze
70
70
 
71
71
  # Indicate that there was an internal error, obviously.
72
- ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n"
72
+ ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze
73
73
 
74
74
  # A common header for indicating the server is too busy. Not used yet.
75
75
  ERROR_503_RESPONSE = "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2011 Evan Phoenix
2
- # Copyright (c) 2005 Zed A. Shaw
2
+ # Copyright (c) 2005 Zed A. Shaw
3
3
 
4
- require 'test/testhelp'
4
+ require 'testhelp'
5
5
 
6
6
  include Puma
7
7
 
@@ -24,11 +24,11 @@ class Http11ParserTest < Test::Unit::TestCase
24
24
  assert_equal 'GET', req['REQUEST_METHOD']
25
25
  assert_nil req['FRAGMENT']
26
26
  assert_nil req['QUERY_STRING']
27
-
27
+
28
28
  parser.reset
29
29
  assert parser.nread == 0, "Number read after reset should be 0"
30
30
  end
31
-
31
+
32
32
  def test_parse_dumbfuck_headers
33
33
  parser = HttpParser.new
34
34
  req = {}
@@ -38,7 +38,7 @@ class Http11ParserTest < Test::Unit::TestCase
38
38
  assert parser.finished?
39
39
  assert !parser.error?
40
40
  end
41
-
41
+
42
42
  def test_parse_error
43
43
  parser = HttpParser.new
44
44
  req = {}
@@ -72,7 +72,7 @@ class Http11ParserTest < Test::Unit::TestCase
72
72
  def rand_data(min, max, readable=true)
73
73
  count = min + ((rand(max)+1) *10).to_i
74
74
  res = count.to_s + "/"
75
-
75
+
76
76
  if readable
77
77
  res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
78
78
  else
@@ -142,4 +142,3 @@ class Http11ParserTest < Test::Unit::TestCase
142
142
 
143
143
  end
144
144
  end
145
-
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.8.0
4
+ version: 2.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-28 00:00:00.000000000 Z
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -84,6 +84,7 @@ executables:
84
84
  extensions:
85
85
  - ext/puma_http11/extconf.rb
86
86
  extra_rdoc_files:
87
+ - DEPLOYMENT.md
87
88
  - History.txt
88
89
  - Manifest.txt
89
90
  - README.md
@@ -95,6 +96,7 @@ extra_rdoc_files:
95
96
  - tools/jungle/upstart/README.md
96
97
  files:
97
98
  - COPYING
99
+ - DEPLOYMENT.md
98
100
  - Gemfile
99
101
  - History.txt
100
102
  - LICENSE
@@ -102,6 +104,7 @@ files:
102
104
  - README.md
103
105
  - Rakefile
104
106
  - bin/puma
107
+ - bin/puma-wild
105
108
  - bin/pumactl
106
109
  - docs/config.md
107
110
  - docs/nginx.md
@@ -152,14 +155,6 @@ files:
152
155
  - lib/puma/util.rb
153
156
  - lib/rack/handler/puma.rb
154
157
  - puma.gemspec
155
- - tools/jungle/README.md
156
- - tools/jungle/init.d/README.md
157
- - tools/jungle/init.d/puma
158
- - tools/jungle/init.d/run-puma
159
- - tools/jungle/upstart/README.md
160
- - tools/jungle/upstart/puma-manager.conf
161
- - tools/jungle/upstart/puma.conf
162
- - tools/trickletest.rb
163
158
  - test/test_app_status.rb
164
159
  - test/test_cli.rb
165
160
  - test/test_config.rb
@@ -177,6 +172,14 @@ files:
177
172
  - test/test_thread_pool.rb
178
173
  - test/test_unix_socket.rb
179
174
  - test/test_ws.rb
175
+ - tools/jungle/README.md
176
+ - tools/jungle/init.d/README.md
177
+ - tools/jungle/init.d/puma
178
+ - tools/jungle/init.d/run-puma
179
+ - tools/jungle/upstart/README.md
180
+ - tools/jungle/upstart/puma-manager.conf
181
+ - tools/jungle/upstart/puma.conf
182
+ - tools/trickletest.rb
180
183
  homepage: http://puma.io
181
184
  licenses:
182
185
  - BSD
@@ -199,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
202
  version: '0'
200
203
  requirements: []
201
204
  rubyforge_project: puma
202
- rubygems_version: 2.0.3
205
+ rubygems_version: 2.2.2
203
206
  signing_key:
204
207
  specification_version: 4
205
208
  summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for