puma 2.8.1 → 2.8.2

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,30 @@
1
+ === 2.8.2 / 2014-04-12
2
+
3
+ * 4 bug fixes:
4
+ * During upgrade, change directory in main process instead of workers.
5
+ * Close the client properly on error
6
+ * Capistrano: fallback from phased restart to start when not started
7
+ * Allow tag option in conf file
8
+
9
+ * 4 doc fixes:
10
+ * Fix Puma daemon service README typo
11
+ * `preload_app!` instead of `preload_app`
12
+ * add preload_app and prune_bundler to example config
13
+ * allow changing of worker_timeout in config file
14
+
15
+ * 11 PRs merged:
16
+ * Merge pull request #487 from ckuttruff/master
17
+ * Merge pull request #492 from ckuttruff/master
18
+ * Merge pull request #493 from alepore/config_tag
19
+ * Merge pull request #503 from mariuz/patch-1
20
+ * Merge pull request #505 from sammcj/patch-1
21
+ * Merge pull request #506 from FlavourSys/config_worker_timeout
22
+ * Merge pull request #510 from momer/rescue-block-handle-servers-fix
23
+ * Merge pull request #511 from macool/patch-1
24
+ * Merge pull request #514 from edogawaconan/refactor_env
25
+ * Merge pull request #517 from misfo/patch-1
26
+ * Merge pull request #518 from LongMan/master
27
+
1
28
  === 2.8.1 / 2014-03-06
2
29
 
3
30
  * 1 bug fixes:
data/README.md CHANGED
@@ -116,6 +116,10 @@ If you're preloading your application and using ActiveRecord, it's recommend you
116
116
  ActiveRecord::Base.establish_connection
117
117
  end
118
118
  end
119
+
120
+ 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 should probably don’t use preload_app.
121
+
122
+ 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.
119
123
 
120
124
  ### Binding TCP / Sockets
121
125
 
@@ -170,6 +174,19 @@ No code is shared between the current and restarted process, so it should be saf
170
174
 
171
175
  If the new process is unable to load, it will simply exit. You should therefore run Puma under a supervisor when using it in production.
172
176
 
177
+ ### Normal vs Hot vs Phased Restart
178
+
179
+ A hot restart means that no requests while deploying your new code will be lost, since the server socket is kept open between restarts.
180
+
181
+ But beware, hot restart does not mean that the incoming requests won’t hang for multiple seconds while your new code has not fully deployed. If you need a zero downtime and zero hanging requests deploy, you must use phased restart.
182
+
183
+ When you run pumactl phased-restart, Puma kills workers one-by-one, meaning that at least another worker is still available to serve requests, which lead in zero hanging request (yay!).
184
+
185
+ But again beware, upgrading an application sometimes involves upgrading the database schema. With phased restart, there may be a moment during the deployment where processes belonging to the previous version and processes belonging to the new version both exist at the same time. Any database schema upgrades you perform must therefore be backwards-compatible with the old application version.
186
+
187
+ if you perform a lot of database migrations, you probably should not use phased restart and use a normal/hot restart instead (pumactl restart). That way, no code is shared while deploying (in that case, preload_app might help for quicker deployment, see below).
188
+
189
+
173
190
  ### Cleanup Code
174
191
 
175
192
  Puma isn't able to understand all the resources that your app may use, so it provides a hook in the configuration file you pass to `-C` called `on_restart`. The block passed to `on_restart` will be called, unsurprisingly, just before Puma restarts itself.
@@ -194,12 +211,21 @@ If you want an easy way to manage multiple scripts at once check [tools/jungle](
194
211
 
195
212
  ## Capistrano deployment
196
213
 
197
- Puma has included Capistrano [deploy script](https://github.com/puma/puma/blob/master/lib/puma/capistrano.rb), you just need require that:
214
+ Puma has support for Capistrano3 with an [external gem](https://github.com/seuros/capistrano-puma), you just need require that in Gemfile:
215
+
216
+ ```ruby
217
+ gem 'capistrano3-puma'
218
+ ```
219
+ And then execute:
220
+
221
+ ```bash
222
+ bundle
223
+ ```
198
224
 
199
- config/deploy.rb
225
+ Then add to Capfile
200
226
 
201
227
  ```ruby
202
- require 'puma/capistrano'
228
+ require 'capistrano/puma'
203
229
  ```
204
230
 
205
231
  and then
data/Rakefile CHANGED
@@ -8,7 +8,6 @@ Hoe.plugin :git
8
8
  Hoe.plugin :ignore
9
9
 
10
10
  HOE = Hoe.spec "puma" do
11
- self.rubyforge_name = 'puma'
12
11
  self.readme_file = "README.md"
13
12
  self.urls = %w!http://puma.io https://github.com/puma/puma!
14
13
 
@@ -42,7 +42,12 @@ Capistrano::Configuration.instance.load do
42
42
 
43
43
  desc 'Restart puma (phased restart)'
44
44
  task :phased_restart, :roles => lambda { puma_role }, :on_no_matching_servers => :continue do
45
- run "cd #{current_path} && #{pumactl_cmd} -S #{state_path} phased-restart"
45
+ begin
46
+ run "cd #{current_path} && #{pumactl_cmd} -S #{state_path} phased-restart"
47
+ rescue Capistrano::CommandError => ex
48
+ puts "Failed to restart puma: #{ex}\nAssuming not started."
49
+ start
50
+ end
46
51
  end
47
52
 
48
53
  end
@@ -257,14 +257,13 @@ module Puma
257
257
  end
258
258
  end
259
259
 
260
- def set_rack_environment
260
+ def env
261
261
  # Try the user option first, then the environment variable,
262
262
  # finally default to development
263
+ @options[:environment] || ENV['RACK_ENV'] || 'development'
264
+ end
263
265
 
264
- env = @options[:environment] ||
265
- ENV['RACK_ENV'] ||
266
- 'development'
267
-
266
+ def set_rack_environment
268
267
  @options[:environment] = env
269
268
  ENV['RACK_ENV'] = env
270
269
  end
@@ -286,13 +285,7 @@ module Puma
286
285
  return
287
286
  end
288
287
 
289
- pos = []
290
-
291
- if env = (@options[:environment] || ENV['RACK_ENV'])
292
- pos << "config/puma/#{env}.rb"
293
- end
294
-
295
- pos << "config/puma.rb"
288
+ pos = ["config/puma/#{env}.rb", "config/puma.rb"]
296
289
  @options[:config_file] = pos.find { |f| File.exist? f }
297
290
  end
298
291
 
@@ -27,6 +27,13 @@ module Puma
27
27
  def start_phased_restart
28
28
  @phase += 1
29
29
  log "- Starting phased worker restart, phase: #{@phase}"
30
+
31
+ # Be sure to change the directory again before loading
32
+ # the app. This way we can pick up new code.
33
+ if dir = @options[:worker_directory]
34
+ log "+ Changing to #{dir}"
35
+ Dir.chdir dir
36
+ end
30
37
  end
31
38
 
32
39
  class Worker
@@ -80,14 +87,12 @@ module Puma
80
87
  def spawn_workers
81
88
  diff = @options[:workers] - @workers.size
82
89
 
83
- upgrade = (@phased_state == :waiting)
84
-
85
90
  master = Process.pid
86
91
 
87
92
  diff.times do
88
93
  idx = next_worker_index
89
94
 
90
- pid = fork { worker(idx, upgrade, master) }
95
+ pid = fork { worker(idx, master) }
91
96
  @cli.debug "Spawned worker: #{pid}"
92
97
  @workers << Worker.new(idx, pid, @phase)
93
98
  @options[:after_worker_boot].each { |h| h.call }
@@ -163,7 +168,7 @@ module Puma
163
168
  end
164
169
  end
165
170
 
166
- def worker(index, upgrade, master)
171
+ def worker(index, master)
167
172
  $0 = "puma: cluster worker #{index}: #{master}"
168
173
  Signal.trap "SIGINT", "IGNORE"
169
174
 
@@ -176,15 +181,6 @@ module Puma
176
181
  exit! 1
177
182
  end
178
183
 
179
- # Be sure to change the directory again before loading
180
- # the app. This way we can pick up new code.
181
- if upgrade
182
- if dir = @options[:worker_directory]
183
- log "+ Changing to #{dir}"
184
- Dir.chdir dir
185
- end
186
- end
187
-
188
184
  # If we're not running under a Bundler context, then
189
185
  # report the info about the context we will be using
190
186
  if !ENV['BUNDLER_GEMFILE'] and File.exist?("Gemfile")
@@ -362,6 +362,16 @@ module Puma
362
362
  def prune_bundler(answer=true)
363
363
  @options[:prune_bundler] = answer
364
364
  end
365
+
366
+ # Additional text to display in process listing
367
+ def tag(string)
368
+ @options[:tag] = string
369
+ end
370
+
371
+ # *Cluster mode only* Set the timeout for workers
372
+ def worker_timeout(timeout)
373
+ @options[:worker_timeout] = timeout
374
+ end
365
375
  end
366
376
  end
367
377
  end
@@ -28,7 +28,7 @@ module Puma
28
28
  # too taxing on performance.
29
29
  module Const
30
30
 
31
- PUMA_VERSION = VERSION = "2.8.1".freeze
31
+ PUMA_VERSION = VERSION = "2.8.2".freeze
32
32
  CODE_NAME = "Sir Edmund Percival Hillary".freeze
33
33
 
34
34
  FAST_TRACK_KA_TIMEOUT = 0.2
@@ -185,8 +185,8 @@ module Puma
185
185
  else
186
186
  begin
187
187
  if io = sock.accept_nonblock
188
- c = Client.new io, nil
189
- pool << c
188
+ client = Client.new io, nil
189
+ pool << client
190
190
  end
191
191
  rescue SystemCallError
192
192
  end
@@ -292,8 +292,8 @@ module Puma
292
292
  else
293
293
  begin
294
294
  if io = sock.accept_nonblock
295
- c = Client.new io, @binder.env(sock)
296
- pool << c
295
+ client = Client.new io, @binder.env(sock)
296
+ pool << client
297
297
  end
298
298
  rescue SystemCallError
299
299
  end
@@ -732,8 +732,8 @@ module Puma
732
732
  begin
733
733
  if io = sock.accept_nonblock
734
734
  count += 1
735
- c = Client.new io, @binder.env(sock)
736
- @thread_pool << c
735
+ client = Client.new io, @binder.env(sock)
736
+ @thread_pool << client
737
737
  end
738
738
  rescue SystemCallError
739
739
  end
@@ -31,7 +31,7 @@ You can add an instance by editing the file or running the following command:
31
31
  The config and log paths are optional parameters and default to:
32
32
 
33
33
  * config: /path/to/app/*config/puma.rb*
34
- * log: /path/to/app/*config/puma.log*
34
+ * log: /path/to/app/*log/puma.log*
35
35
 
36
36
  To remove an app, simply delete the line from the config file or run:
37
37
 
metadata CHANGED
@@ -1,77 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.1
4
+ version: 2.8.2
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Evan Phoenix
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-03-06 00:00:00.000000000 Z
12
+ date: 2014-04-12 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rack
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - ">="
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '1.1'
20
- - - "<"
22
+ - - <
21
23
  - !ruby/object:Gem::Version
22
24
  version: '2.0'
23
25
  type: :runtime
24
26
  prerelease: false
25
27
  version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
26
29
  requirements:
27
- - - ">="
30
+ - - ! '>='
28
31
  - !ruby/object:Gem::Version
29
32
  version: '1.1'
30
- - - "<"
33
+ - - <
31
34
  - !ruby/object:Gem::Version
32
35
  version: '2.0'
33
36
  - !ruby/object:Gem::Dependency
34
37
  name: rdoc
35
38
  requirement: !ruby/object:Gem::Requirement
39
+ none: false
36
40
  requirements:
37
- - - "~>"
41
+ - - ~>
38
42
  - !ruby/object:Gem::Version
39
43
  version: '4.0'
40
44
  type: :development
41
45
  prerelease: false
42
46
  version_requirements: !ruby/object:Gem::Requirement
47
+ none: false
43
48
  requirements:
44
- - - "~>"
49
+ - - ~>
45
50
  - !ruby/object:Gem::Version
46
51
  version: '4.0'
47
52
  - !ruby/object:Gem::Dependency
48
53
  name: rake-compiler
49
54
  requirement: !ruby/object:Gem::Requirement
55
+ none: false
50
56
  requirements:
51
- - - "~>"
57
+ - - ~>
52
58
  - !ruby/object:Gem::Version
53
59
  version: 0.8.0
54
60
  type: :development
55
61
  prerelease: false
56
62
  version_requirements: !ruby/object:Gem::Requirement
63
+ none: false
57
64
  requirements:
58
- - - "~>"
65
+ - - ~>
59
66
  - !ruby/object:Gem::Version
60
67
  version: 0.8.0
61
68
  - !ruby/object:Gem::Dependency
62
69
  name: hoe
63
70
  requirement: !ruby/object:Gem::Requirement
71
+ none: false
64
72
  requirements:
65
- - - "~>"
73
+ - - ~>
66
74
  - !ruby/object:Gem::Version
67
- version: '3.9'
75
+ version: '3.6'
68
76
  type: :development
69
77
  prerelease: false
70
78
  version_requirements: !ruby/object:Gem::Requirement
79
+ none: false
71
80
  requirements:
72
- - - "~>"
81
+ - - ~>
73
82
  - !ruby/object:Gem::Version
74
- version: '3.9'
83
+ version: '3.6'
75
84
  description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
76
85
  for Ruby/Rack applications. Puma is intended for use in both development and production
77
86
  environments. In order to get the best throughput, it is highly recommended that
@@ -155,6 +164,14 @@ files:
155
164
  - lib/puma/util.rb
156
165
  - lib/rack/handler/puma.rb
157
166
  - puma.gemspec
167
+ - tools/jungle/README.md
168
+ - tools/jungle/init.d/README.md
169
+ - tools/jungle/init.d/puma
170
+ - tools/jungle/init.d/run-puma
171
+ - tools/jungle/upstart/README.md
172
+ - tools/jungle/upstart/puma-manager.conf
173
+ - tools/jungle/upstart/puma.conf
174
+ - tools/trickletest.rb
158
175
  - test/test_app_status.rb
159
176
  - test/test_cli.rb
160
177
  - test/test_config.rb
@@ -172,39 +189,32 @@ files:
172
189
  - test/test_thread_pool.rb
173
190
  - test/test_unix_socket.rb
174
191
  - 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
183
192
  homepage: http://puma.io
184
193
  licenses:
185
194
  - BSD
186
- metadata: {}
187
195
  post_install_message:
188
196
  rdoc_options:
189
- - "--main"
197
+ - --main
190
198
  - README.md
191
199
  require_paths:
192
200
  - lib
193
201
  required_ruby_version: !ruby/object:Gem::Requirement
202
+ none: false
194
203
  requirements:
195
- - - ">="
204
+ - - ! '>='
196
205
  - !ruby/object:Gem::Version
197
206
  version: 1.8.7
198
207
  required_rubygems_version: !ruby/object:Gem::Requirement
208
+ none: false
199
209
  requirements:
200
- - - ">="
210
+ - - ! '>='
201
211
  - !ruby/object:Gem::Version
202
212
  version: '0'
203
213
  requirements: []
204
214
  rubyforge_project: puma
205
- rubygems_version: 2.2.2
215
+ rubygems_version: 1.8.25
206
216
  signing_key:
207
- specification_version: 4
217
+ specification_version: 3
208
218
  summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
209
219
  Ruby/Rack applications
210
220
  test_files:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 74aab6aaab377487d53393978bbb59ffae181f66
4
- data.tar.gz: 383b6735116a87480a5c73403107de1941da3e99
5
- SHA512:
6
- metadata.gz: 2d9663eec2cf39f8e7471937887633cb56a6b8a8989ab3055a8c64497637decc45b56b9d87d2873004ee56665ba9d8386da28c1dd9d216ff9c15942a5961a1e5
7
- data.tar.gz: e65857e59cda95b3980761ec5bf8b00f55c55fa1798d6dc43c56c775e84872f7d36d28a5260c232c360f354d4fe865fcc9a76e731b1430e7f26d6291066c60fd