puma 3.10.0-java → 3.11.0-java
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 +4 -4
- data/History.md +21 -0
- data/README.md +9 -4
- data/docs/architecture.md +36 -0
- data/docs/deployment.md +91 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/ext/puma_http11/mini_ssl.c +6 -1
- data/lib/puma/cli.rb +4 -0
- data/lib/puma/cluster.rb +1 -1
- data/lib/puma/configuration.rb +15 -11
- data/lib/puma/const.rb +6 -2
- data/lib/puma/control_cli.rb +1 -1
- data/lib/puma/dsl.rb +4 -0
- data/lib/puma/launcher.rb +2 -2
- data/lib/puma/minissl.rb +19 -1
- data/lib/puma/runner.rb +4 -0
- data/lib/puma/server.rb +20 -1
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6faf171c74eac3ee1844512420a0cc79ebd1a4aa9854d12953ba9cef5c66d9c
|
4
|
+
data.tar.gz: aac1e3c847905d68c5c939a73553225b4ef7d3232eb268246fda46897996cb6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddad91f3b41a77fb8f4e86239f3aae27330a62a2deaf586353cd3c36abd8537409a77a9150a0bc7d012c04ad989d524b5ca48dc3fd0639bbdaf96b0ff8685de6
|
7
|
+
data.tar.gz: 33f6829e2a05e7fe0e567bee7c6a28a6dd0a4ce07d3176f81c9a9d3100b6cfc8ccca60b20b4edf0fc1ed5d99ccbc62bb3f869dc8eeb4a2489dbbbf71a96bf76b
|
data/History.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
## 3.11.0 / 2017-11-20
|
2
|
+
|
3
|
+
* 2 features:
|
4
|
+
* HTTP 203 Early Hints (#1403)
|
5
|
+
* 421/451 status codes now have correct status messages attached (#1435)
|
6
|
+
|
7
|
+
* 9 bugfixes:
|
8
|
+
* Environment config files (/config/puma/<ENV>.rb) load correctly (#1340)
|
9
|
+
* Specify windows dependencies correctly (#1434, #1436)
|
10
|
+
* puma/events required in test helper (#1418)
|
11
|
+
* Correct control CLI's option help text (#1416)
|
12
|
+
* Remove a warning for unused variable in mini_ssl (#1409)
|
13
|
+
* Correct pumactl docs argument ordering (#1427)
|
14
|
+
* Fix an uninitialized variable warning in server.rb (#1430)
|
15
|
+
* Fix docs typo/error in Launcher init (#1429)
|
16
|
+
* Deal with leading spaces in RUBYOPT (#1455)
|
17
|
+
|
18
|
+
* 2 other:
|
19
|
+
* Add docs about internals (#1425, #1452)
|
20
|
+
* Tons of test fixes from @MSP-Greg (#1439, #1442, #1464)
|
21
|
+
|
1
22
|
## 3.10.0 / 2017-08-17
|
2
23
|
|
3
24
|
* 3 features:
|
data/README.md
CHANGED
@@ -74,6 +74,8 @@ $ puma -t 8:32
|
|
74
74
|
|
75
75
|
Puma will automatically scale the number of threads, from the minimum until it caps out at the maximum, based on how much traffic is present. The current default is `0:16`. Feel free to experiment, but be careful not to set the number of maximum threads to a large number, as you may exhaust resources on the system (or hit resource limits).
|
76
76
|
|
77
|
+
Be aware that additionally Puma creates threads on its own for internal purposes (e.g. handling slow clients). So even if you specify -t 1:1, expect around 7 threads created in your application.
|
78
|
+
|
77
79
|
### Clustered mode
|
78
80
|
|
79
81
|
Puma also offers "clustered mode". Clustered mode `fork`s workers from a master process. Each child process still has its own thread pool. You can tune the number of workers with the `-w` (or `--workers`) flag:
|
@@ -173,7 +175,7 @@ Puma will start the control server on localhost port 9293. All requests to the c
|
|
173
175
|
You can also interact with the control server via `pumactl`. This command will restart Puma:
|
174
176
|
|
175
177
|
```
|
176
|
-
$ pumactl
|
178
|
+
$ pumactl -C 'tcp://127.0.0.1:9293' --control-token foo restart
|
177
179
|
```
|
178
180
|
|
179
181
|
To see a list of `pumactl` options, use `pumactl --help`.
|
@@ -215,11 +217,14 @@ Some platforms do not support all Puma features.
|
|
215
217
|
|
216
218
|
## Known Bugs
|
217
219
|
|
218
|
-
For MRI versions 2.2.7, 2.3.4 and 2.4.1, you may see ```stream closed in another thread (IOError)```. It may be caused by a [Ruby bug](https://bugs.ruby-lang.org/issues/13632). It can be fixed with the gem https://rubygems.org/gems/stopgap_13632:
|
220
|
+
For MRI versions 2.2.7, 2.2.8, 2.3.4 and 2.4.1, you may see ```stream closed in another thread (IOError)```. It may be caused by a [Ruby bug](https://bugs.ruby-lang.org/issues/13632). It can be fixed with the gem https://rubygems.org/gems/stopgap_13632:
|
219
221
|
|
220
222
|
```ruby
|
221
|
-
if %w(2.2.7 2.3.4 2.4.1).include? RUBY_VERSION
|
222
|
-
|
223
|
+
if %w(2.2.7 2.2.8 2.3.4 2.4.1).include? RUBY_VERSION
|
224
|
+
begin
|
225
|
+
require 'stopgap_13632'
|
226
|
+
rescue LoadError
|
227
|
+
end
|
223
228
|
end
|
224
229
|
```
|
225
230
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Architecture
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
![http://bit.ly/2iJuFky](images/puma-general-arch.png)
|
6
|
+
|
7
|
+
Puma is a threaded web server, processing requests across a TCP or UNIX socket.
|
8
|
+
|
9
|
+
Workers accept connections from the socket and a thread in the worker's thread pool processes the client's request.
|
10
|
+
|
11
|
+
Clustered mode is shown/discussed here. Single mode is analogous to having a single worker process.
|
12
|
+
|
13
|
+
## Connection pipeline
|
14
|
+
|
15
|
+
![http://bit.ly/2zwzhEK](images/puma-connection-flow.png)
|
16
|
+
|
17
|
+
* Upon startup, Puma listens on a TCP or UNIX socket.
|
18
|
+
* The backlog of this socket is configured (with a default of 1024), determining how many established but unaccepted connections can exist concurrently.
|
19
|
+
* This socket backlog is distinct from the "backlog" of work as reported by the control server stats. The latter is the number of connections in that worker's "todo" set waiting for a worker thread.
|
20
|
+
* By default, a single, separate thread is used to receive HTTP requests across the socket.
|
21
|
+
* When at least one worker thread is available for work, a connection is accepted and placed in this request buffer
|
22
|
+
* This thread waits for entire HTTP requests to be received over the connection
|
23
|
+
* Once received, the connection is pushed into the "todo" set
|
24
|
+
* Worker threads pop work off the "todo" set for processing
|
25
|
+
* The thread processes the request via the rack application (which generates the HTTP response)
|
26
|
+
* The thread writes the response to the connection
|
27
|
+
* Finally, the thread become available to process another connection in the "todo" set
|
28
|
+
|
29
|
+
### Disabling `queue_requests`
|
30
|
+
|
31
|
+
![http://bit.ly/2zxCJ1Z](images/puma-connection-flow-no-reactor.png)
|
32
|
+
|
33
|
+
The `queue_requests` option is `true` by default, enabling the separate thread used to buffer requests as described above.
|
34
|
+
|
35
|
+
If set to `false`, this buffer will not be used for connections while waiting for the request to arrive.
|
36
|
+
In this mode, when a connection is accepted, it is added to the "todo" queue immediately, and a worker will syncronously do any waiting necessarry to read the HTTP request from the socket.
|
data/docs/deployment.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Deployment engineering for puma
|
2
|
+
|
3
|
+
Puma is software that is expected to be run in a deployed environment eventually.
|
4
|
+
You can certainly 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 conceived 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 16 and that's 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 Ruby code 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 `upstart` 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. It is not compatible with phased-restart and `prune_bundler` as well.
|
80
|
+
|
81
|
+
1. Use `prune_bundler`. This makes it so that the cluster master will detach itself
|
82
|
+
from a Bundler context on start. This allows the cluster workers to load your app
|
83
|
+
and start a brand new Bundler context within the worker only. This means your
|
84
|
+
master remains pristine and can live on between new releases of your code.
|
85
|
+
|
86
|
+
1. Use phased-restart (`SIGUSR1` or `pumactl phased-restart`). This tells the master
|
87
|
+
to kill off one worker at a time and restart them in your new code. This minimizes
|
88
|
+
downtime and staggers the restart nicely. **WARNING** This means that both your
|
89
|
+
old code and your new code will be running concurrently. Most deployment solutions
|
90
|
+
already cause that, but it's worth warning you about it again. Be careful with your
|
91
|
+
migrations, etc!
|
Binary file
|
Binary file
|
Binary file
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -411,6 +411,11 @@ VALUE noop(VALUE self) {
|
|
411
411
|
void Init_mini_ssl(VALUE puma) {
|
412
412
|
VALUE mod, eng;
|
413
413
|
|
414
|
+
/* Fake operation for documentation (RDoc, YARD) */
|
415
|
+
#if 0 == 1
|
416
|
+
puma = rb_define_module("Puma");
|
417
|
+
#endif
|
418
|
+
|
414
419
|
SSL_library_init();
|
415
420
|
OpenSSL_add_ssl_algorithms();
|
416
421
|
SSL_load_error_strings();
|
@@ -447,7 +452,7 @@ VALUE raise_error(VALUE self) {
|
|
447
452
|
}
|
448
453
|
|
449
454
|
void Init_mini_ssl(VALUE puma) {
|
450
|
-
VALUE mod
|
455
|
+
VALUE mod;
|
451
456
|
|
452
457
|
mod = rb_define_module_under(puma, "MiniSSL");
|
453
458
|
rb_define_class_under(mod, "SSLError", rb_eStandardError);
|
data/lib/puma/cli.rb
CHANGED
@@ -181,6 +181,10 @@ module Puma
|
|
181
181
|
user_config.tcp_mode!
|
182
182
|
end
|
183
183
|
|
184
|
+
o.on "--early-hints", "Enable early hints support" do
|
185
|
+
user_config.early_hints
|
186
|
+
end
|
187
|
+
|
184
188
|
o.on "-V", "--version", "Print the version information" do
|
185
189
|
puts "puma version #{Puma::Const::VERSION}"
|
186
190
|
exit 0
|
data/lib/puma/cluster.rb
CHANGED
data/lib/puma/configuration.rb
CHANGED
@@ -189,22 +189,22 @@ module Puma
|
|
189
189
|
end
|
190
190
|
|
191
191
|
def load
|
192
|
+
config_files.each { |config_file| @file_dsl._load_from(config_file) }
|
193
|
+
|
194
|
+
@options
|
195
|
+
end
|
196
|
+
|
197
|
+
def config_files
|
192
198
|
files = @options.all_of(:config_files)
|
193
199
|
|
194
|
-
if files
|
195
|
-
|
196
|
-
File.exist?(f)
|
197
|
-
}
|
200
|
+
return [] if files == ['-']
|
201
|
+
return files if files.any?
|
198
202
|
|
199
|
-
|
200
|
-
|
201
|
-
files = []
|
203
|
+
first_default_file = %W(config/puma/#{environment_str}.rb config/puma.rb).find do |f|
|
204
|
+
File.exist?(f)
|
202
205
|
end
|
203
206
|
|
204
|
-
|
205
|
-
@file_dsl._load_from(f)
|
206
|
-
end
|
207
|
-
@options
|
207
|
+
[first_default_file]
|
208
208
|
end
|
209
209
|
|
210
210
|
# Call once all configuration (included from rackup files)
|
@@ -264,6 +264,10 @@ module Puma
|
|
264
264
|
@options[:environment]
|
265
265
|
end
|
266
266
|
|
267
|
+
def environment_str
|
268
|
+
environment.respond_to?(:call) ? environment.call : environment
|
269
|
+
end
|
270
|
+
|
267
271
|
def load_plugin(name)
|
268
272
|
@plugins.create name
|
269
273
|
end
|
data/lib/puma/const.rb
CHANGED
@@ -54,6 +54,7 @@ module Puma
|
|
54
54
|
416 => 'Range Not Satisfiable',
|
55
55
|
417 => 'Expectation Failed',
|
56
56
|
418 => 'I\'m A Teapot',
|
57
|
+
421 => 'Misdirected Request',
|
57
58
|
422 => 'Unprocessable Entity',
|
58
59
|
423 => 'Locked',
|
59
60
|
424 => 'Failed Dependency',
|
@@ -61,6 +62,7 @@ module Puma
|
|
61
62
|
428 => 'Precondition Required',
|
62
63
|
429 => 'Too Many Requests',
|
63
64
|
431 => 'Request Header Fields Too Large',
|
65
|
+
451 => 'Unavailable For Legal Reasons',
|
64
66
|
500 => 'Internal Server Error',
|
65
67
|
501 => 'Not Implemented',
|
66
68
|
502 => 'Bad Gateway',
|
@@ -96,8 +98,8 @@ module Puma
|
|
96
98
|
# too taxing on performance.
|
97
99
|
module Const
|
98
100
|
|
99
|
-
PUMA_VERSION = VERSION = "3.
|
100
|
-
CODE_NAME = "
|
101
|
+
PUMA_VERSION = VERSION = "3.11.0".freeze
|
102
|
+
CODE_NAME = "Love Song".freeze
|
101
103
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
102
104
|
|
103
105
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
@@ -221,5 +223,7 @@ module Puma
|
|
221
223
|
HIJACK_P = "rack.hijack?".freeze
|
222
224
|
HIJACK = "rack.hijack".freeze
|
223
225
|
HIJACK_IO = "rack.hijack_io".freeze
|
226
|
+
|
227
|
+
EARLY_HINTS = "rack.early_hints".freeze
|
224
228
|
end
|
225
229
|
end
|
data/lib/puma/control_cli.rb
CHANGED
@@ -245,7 +245,7 @@ module Puma
|
|
245
245
|
run_args += ["-S", @state] if @state
|
246
246
|
run_args += ["-q"] if @quiet
|
247
247
|
run_args += ["--pidfile", @pidfile] if @pidfile
|
248
|
-
run_args += ["--control", @control_url] if @control_url
|
248
|
+
run_args += ["--control-url", @control_url] if @control_url
|
249
249
|
run_args += ["--control-token", @control_auth_token] if @control_auth_token
|
250
250
|
run_args += ["-C", @config_file] if @config_file
|
251
251
|
|
data/lib/puma/dsl.rb
CHANGED
@@ -241,6 +241,10 @@ module Puma
|
|
241
241
|
@options[:mode] = :tcp
|
242
242
|
end
|
243
243
|
|
244
|
+
def early_hints(answer=true)
|
245
|
+
@options[:early_hints] = answer
|
246
|
+
end
|
247
|
+
|
244
248
|
# Redirect STDOUT and STDERR to files specified.
|
245
249
|
def stdout_redirect(stdout=nil, stderr=nil, append=false)
|
246
250
|
@options[:redirect_stdout] = stdout
|
data/lib/puma/launcher.rb
CHANGED
@@ -40,7 +40,7 @@ module Puma
|
|
40
40
|
# [200, {}, ["hello world"]]
|
41
41
|
# end
|
42
42
|
# end
|
43
|
-
# Puma::Launcher.new(conf,
|
43
|
+
# Puma::Launcher.new(conf, events: Puma::Events.stdio).run
|
44
44
|
def initialize(conf, launcher_args={})
|
45
45
|
@runner = nil
|
46
46
|
@events = launcher_args[:events] || Events::DEFAULT
|
@@ -168,7 +168,7 @@ module Puma
|
|
168
168
|
env = Bundler::ORIGINAL_ENV.dup
|
169
169
|
# add -rbundler/setup so we load from Gemfile when restarting
|
170
170
|
bundle = "-rbundler/setup"
|
171
|
-
env["RUBYOPT"] = [env["RUBYOPT"], bundle].join(" ") unless env["RUBYOPT"].to_s.include?(bundle)
|
171
|
+
env["RUBYOPT"] = [env["RUBYOPT"], bundle].join(" ").lstrip unless env["RUBYOPT"].to_s.include?(bundle)
|
172
172
|
env
|
173
173
|
else
|
174
174
|
ENV.to_h
|
data/lib/puma/minissl.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
begin
|
2
|
+
require 'io/wait'
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
|
1
6
|
module Puma
|
2
7
|
module MiniSSL
|
3
8
|
class Socket
|
@@ -43,7 +48,20 @@ module Puma
|
|
43
48
|
output = engine_read_all
|
44
49
|
return output if output
|
45
50
|
|
46
|
-
|
51
|
+
begin
|
52
|
+
data = @socket.read_nonblock(size, exception: false)
|
53
|
+
if data == :wait_readable || data == :wait_writable
|
54
|
+
if @socket.to_io.respond_to?(data)
|
55
|
+
@socket.to_io.__send__(data)
|
56
|
+
elsif data == :wait_readable
|
57
|
+
IO.select([@socket.to_io])
|
58
|
+
else
|
59
|
+
IO.select(nil, [@socket.to_io])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
break
|
63
|
+
end
|
64
|
+
end while true
|
47
65
|
|
48
66
|
@engine.inject(data)
|
49
67
|
output = engine_read_all
|
data/lib/puma/runner.rb
CHANGED
data/lib/puma/server.rb
CHANGED
@@ -62,6 +62,7 @@ module Puma
|
|
62
62
|
|
63
63
|
@thread = nil
|
64
64
|
@thread_pool = nil
|
65
|
+
@early_hints = nil
|
65
66
|
|
66
67
|
@persistent_timeout = options.fetch(:persistent_timeout, PERSISTENT_TIMEOUT)
|
67
68
|
@first_data_timeout = options.fetch(:first_data_timeout, FIRST_DATA_TIMEOUT)
|
@@ -81,7 +82,7 @@ module Puma
|
|
81
82
|
@precheck_closing = true
|
82
83
|
end
|
83
84
|
|
84
|
-
attr_accessor :binder, :leak_stack_on_error
|
85
|
+
attr_accessor :binder, :leak_stack_on_error, :early_hints
|
85
86
|
|
86
87
|
forward :add_tcp_listener, :@binder
|
87
88
|
forward :add_ssl_listener, :@binder
|
@@ -595,6 +596,24 @@ module Puma
|
|
595
596
|
env[RACK_INPUT] = body
|
596
597
|
env[RACK_URL_SCHEME] = env[HTTPS_KEY] ? HTTPS : HTTP
|
597
598
|
|
599
|
+
if @early_hints
|
600
|
+
env[EARLY_HINTS] = lambda { |headers|
|
601
|
+
fast_write client, "HTTP/1.1 103 Early Hints\r\n".freeze
|
602
|
+
|
603
|
+
headers.each_pair do |k, vs|
|
604
|
+
if vs.respond_to?(:to_s) && !vs.to_s.empty?
|
605
|
+
vs.to_s.split(NEWLINE).each do |v|
|
606
|
+
fast_write client, "#{k}: #{v}\r\n"
|
607
|
+
end
|
608
|
+
else
|
609
|
+
fast_write client, "#{k}: #{v}\r\n"
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
fast_write client, "\r\n".freeze
|
614
|
+
}
|
615
|
+
end
|
616
|
+
|
598
617
|
# A rack extension. If the app writes #call'ables to this
|
599
618
|
# array, we will invoke them when the request is done.
|
600
619
|
#
|
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: 3.
|
4
|
+
version: 3.11.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
|
14
14
|
for Ruby/Rack applications. Puma is intended for use in both development and production
|
@@ -28,6 +28,11 @@ files:
|
|
28
28
|
- bin/puma
|
29
29
|
- bin/puma-wild
|
30
30
|
- bin/pumactl
|
31
|
+
- docs/architecture.md
|
32
|
+
- docs/deployment.md
|
33
|
+
- docs/images/puma-connection-flow-no-reactor.png
|
34
|
+
- docs/images/puma-connection-flow.png
|
35
|
+
- docs/images/puma-general-arch.png
|
31
36
|
- docs/nginx.md
|
32
37
|
- docs/plugins.md
|
33
38
|
- docs/restart.md
|
@@ -98,7 +103,8 @@ files:
|
|
98
103
|
homepage: http://puma.io
|
99
104
|
licenses:
|
100
105
|
- BSD-3-Clause
|
101
|
-
metadata:
|
106
|
+
metadata:
|
107
|
+
msys2_mingw_dependencies: openssl
|
102
108
|
post_install_message:
|
103
109
|
rdoc_options: []
|
104
110
|
require_paths:
|
@@ -115,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
121
|
version: '0'
|
116
122
|
requirements: []
|
117
123
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.6.
|
124
|
+
rubygems_version: 2.6.13
|
119
125
|
signing_key:
|
120
126
|
specification_version: 4
|
121
127
|
summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
|