puma 5.6.7 → 6.4.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.

Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +269 -13
  3. data/README.md +78 -29
  4. data/bin/puma-wild +1 -1
  5. data/docs/compile_options.md +34 -0
  6. data/docs/fork_worker.md +1 -3
  7. data/docs/kubernetes.md +12 -0
  8. data/docs/nginx.md +1 -1
  9. data/docs/systemd.md +1 -2
  10. data/docs/testing_benchmarks_local_files.md +150 -0
  11. data/docs/testing_test_rackup_ci_files.md +36 -0
  12. data/ext/puma_http11/extconf.rb +11 -8
  13. data/ext/puma_http11/http11_parser.c +1 -1
  14. data/ext/puma_http11/http11_parser.h +1 -1
  15. data/ext/puma_http11/http11_parser.java.rl +2 -2
  16. data/ext/puma_http11/http11_parser.rl +2 -2
  17. data/ext/puma_http11/http11_parser_common.rl +2 -2
  18. data/ext/puma_http11/mini_ssl.c +122 -18
  19. data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
  20. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
  21. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +156 -53
  22. data/ext/puma_http11/puma_http11.c +17 -9
  23. data/lib/puma/app/status.rb +4 -4
  24. data/lib/puma/binder.rb +50 -53
  25. data/lib/puma/cli.rb +16 -18
  26. data/lib/puma/client.rb +59 -19
  27. data/lib/puma/cluster/worker.rb +18 -11
  28. data/lib/puma/cluster/worker_handle.rb +4 -1
  29. data/lib/puma/cluster.rb +33 -30
  30. data/lib/puma/commonlogger.rb +21 -14
  31. data/lib/puma/configuration.rb +78 -58
  32. data/lib/puma/const.rb +129 -92
  33. data/lib/puma/control_cli.rb +15 -11
  34. data/lib/puma/detect.rb +4 -0
  35. data/lib/puma/dsl.rb +237 -56
  36. data/lib/puma/error_logger.rb +18 -9
  37. data/lib/puma/events.rb +6 -126
  38. data/lib/puma/io_buffer.rb +39 -4
  39. data/lib/puma/jruby_restart.rb +2 -1
  40. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  41. data/lib/puma/launcher.rb +102 -175
  42. data/lib/puma/log_writer.rb +147 -0
  43. data/lib/puma/minissl/context_builder.rb +24 -12
  44. data/lib/puma/minissl.rb +99 -11
  45. data/lib/puma/plugin/systemd.rb +90 -0
  46. data/lib/puma/plugin/tmp_restart.rb +1 -1
  47. data/lib/puma/rack/builder.rb +6 -6
  48. data/lib/puma/rack/urlmap.rb +1 -1
  49. data/lib/puma/rack_default.rb +19 -4
  50. data/lib/puma/reactor.rb +19 -10
  51. data/lib/puma/request.rb +365 -170
  52. data/lib/puma/runner.rb +56 -20
  53. data/lib/puma/sd_notify.rb +149 -0
  54. data/lib/puma/server.rb +116 -89
  55. data/lib/puma/single.rb +13 -11
  56. data/lib/puma/state_file.rb +1 -4
  57. data/lib/puma/thread_pool.rb +57 -19
  58. data/lib/puma/util.rb +0 -11
  59. data/lib/puma.rb +9 -10
  60. data/lib/rack/handler/puma.rb +113 -86
  61. metadata +9 -5
  62. data/lib/puma/queue_close.rb +0 -26
  63. data/lib/puma/systemd.rb +0 -46
  64. data/lib/rack/version_restriction.rb +0 -15
data/lib/puma.rb CHANGED
@@ -3,23 +3,24 @@
3
3
  # Standard libraries
4
4
  require 'socket'
5
5
  require 'tempfile'
6
- require 'time'
7
- require 'etc'
8
6
  require 'uri'
9
7
  require 'stringio'
10
8
 
11
9
  require 'thread'
12
10
 
13
- # extension files should not be loaded with `require_relative`
11
+ # use require, see https://github.com/puma/puma/pull/2381
14
12
  require 'puma/puma_http11'
13
+
15
14
  require_relative 'puma/detect'
16
15
  require_relative 'puma/json_serialization'
17
- require_relative 'rack/version_restriction'
18
16
 
19
17
  module Puma
20
- autoload :Const, 'puma/const'
21
- autoload :Server, 'puma/server'
22
- autoload :Launcher, 'puma/launcher'
18
+ # when Puma is loaded via `Puma::CLI`, all files are loaded via
19
+ # `require_relative`. The below are for non-standard loading
20
+ autoload :Const, "#{__dir__}/puma/const"
21
+ autoload :Server, "#{__dir__}/puma/server"
22
+ autoload :Launcher, "#{__dir__}/puma/launcher"
23
+ autoload :LogWriter, "#{__dir__}/puma/log_writer"
23
24
 
24
25
  # at present, MiniSSL::Engine is only defined in extension code (puma_http11),
25
26
  # not in minissl.rb
@@ -28,7 +29,7 @@ module Puma
28
29
  HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
29
30
 
30
31
  if HAS_SSL
31
- require 'puma/minissl'
32
+ require_relative 'puma/minissl'
32
33
  else
33
34
  module MiniSSL
34
35
  # this class is defined so that it exists when Puma is compiled
@@ -71,9 +72,7 @@ module Puma
71
72
  @get_stats.stats
72
73
  end
73
74
 
74
- # Thread name is new in Ruby 2.3
75
75
  def self.set_thread_name(name)
76
- return unless Thread.current.respond_to?(:name=)
77
76
  Thread.current.name = "puma #{name}"
78
77
  end
79
78
  end
@@ -1,114 +1,141 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rack/handler'
4
-
5
- module Rack
6
- module Handler
7
- module Puma
8
- DEFAULT_OPTIONS = {
9
- :Verbose => false,
10
- :Silent => false
11
- }
12
-
13
- def self.config(app, options = {})
14
- require 'puma'
15
- require 'puma/configuration'
16
- require 'puma/events'
17
- require 'puma/launcher'
18
-
19
- default_options = DEFAULT_OPTIONS.dup
20
-
21
- # Libraries pass in values such as :Port and there is no way to determine
22
- # if it is a default provided by the library or a special value provided
23
- # by the user. A special key `user_supplied_options` can be passed. This
24
- # contains an array of all explicitly defined user options. We then
25
- # know that all other values are defaults
26
- if user_supplied_options = options.delete(:user_supplied_options)
27
- (options.keys - user_supplied_options).each do |k|
28
- default_options[k] = options.delete(k)
29
- end
3
+ # This module is used as an 'include' file in code at bottom of file
4
+ module Puma
5
+ module RackHandler
6
+ DEFAULT_OPTIONS = {
7
+ :Verbose => false,
8
+ :Silent => false
9
+ }
10
+
11
+ def config(app, options = {})
12
+ require_relative '../../puma'
13
+ require_relative '../../puma/configuration'
14
+ require_relative '../../puma/log_writer'
15
+ require_relative '../../puma/launcher'
16
+
17
+ default_options = DEFAULT_OPTIONS.dup
18
+
19
+ # Libraries pass in values such as :Port and there is no way to determine
20
+ # if it is a default provided by the library or a special value provided
21
+ # by the user. A special key `user_supplied_options` can be passed. This
22
+ # contains an array of all explicitly defined user options. We then
23
+ # know that all other values are defaults
24
+ if user_supplied_options = options.delete(:user_supplied_options)
25
+ (options.keys - user_supplied_options).each do |k|
26
+ default_options[k] = options.delete(k)
30
27
  end
28
+ end
31
29
 
32
- conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
33
- if options.delete(:Verbose)
34
- require 'rack/common_logger'
35
- app = Rack::CommonLogger.new(app, STDOUT)
36
- end
30
+ @events = options[:events] || ::Puma::Events.new
37
31
 
38
- if options[:environment]
39
- user_config.environment options[:environment]
32
+ conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
33
+ if options.delete(:Verbose)
34
+ begin
35
+ require 'rack/commonlogger' # Rack 1.x
36
+ rescue LoadError
37
+ require 'rack/common_logger' # Rack 2 and later
40
38
  end
39
+ app = ::Rack::CommonLogger.new(app, STDOUT)
40
+ end
41
41
 
42
- if options[:Threads]
43
- min, max = options.delete(:Threads).split(':', 2)
44
- user_config.threads min, max
45
- end
42
+ if options[:environment]
43
+ user_config.environment options[:environment]
44
+ end
46
45
 
47
- if options[:Host] || options[:Port]
48
- host = options[:Host] || default_options[:Host]
49
- port = options[:Port] || default_options[:Port]
50
- self.set_host_port_to_config(host, port, user_config)
51
- end
46
+ if options[:Threads]
47
+ min, max = options.delete(:Threads).split(':', 2)
48
+ user_config.threads min, max
49
+ end
52
50
 
53
- if default_options[:Host]
54
- file_config.set_default_host(default_options[:Host])
55
- end
56
- self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
51
+ if options[:Host] || options[:Port]
52
+ host = options[:Host] || default_options[:Host]
53
+ port = options[:Port] || default_options[:Port]
54
+ self.set_host_port_to_config(host, port, user_config)
55
+ end
57
56
 
58
- user_config.app app
57
+ if default_options[:Host]
58
+ file_config.set_default_host(default_options[:Host])
59
59
  end
60
- conf
60
+ self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
61
+
62
+ user_config.app app
61
63
  end
64
+ conf
65
+ end
62
66
 
63
- def self.run(app, **options)
64
- conf = self.config(app, options)
67
+ def run(app, **options)
68
+ conf = self.config(app, options)
65
69
 
66
- events = options.delete(:Silent) ? ::Puma::Events.strings : ::Puma::Events.stdio
70
+ log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
67
71
 
68
- launcher = ::Puma::Launcher.new(conf, :events => events)
72
+ launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
69
73
 
70
- yield launcher if block_given?
71
- begin
72
- launcher.run
73
- rescue Interrupt
74
- puts "* Gracefully stopping, waiting for requests to finish"
75
- launcher.stop
76
- puts "* Goodbye!"
77
- end
74
+ yield launcher if block_given?
75
+ begin
76
+ launcher.run
77
+ rescue Interrupt
78
+ puts "* Gracefully stopping, waiting for requests to finish"
79
+ launcher.stop
80
+ puts "* Goodbye!"
78
81
  end
82
+ end
79
83
 
80
- def self.valid_options
81
- {
82
- "Host=HOST" => "Hostname to listen on (default: localhost)",
83
- "Port=PORT" => "Port to listen on (default: 8080)",
84
- "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
85
- "Verbose" => "Don't report each request (default: false)"
86
- }
87
- end
84
+ def valid_options
85
+ {
86
+ "Host=HOST" => "Hostname to listen on (default: localhost)",
87
+ "Port=PORT" => "Port to listen on (default: 8080)",
88
+ "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
89
+ "Verbose" => "Don't report each request (default: false)"
90
+ }
91
+ end
88
92
 
89
- def self.set_host_port_to_config(host, port, config)
90
- config.clear_binds! if host || port
93
+ def set_host_port_to_config(host, port, config)
94
+ config.clear_binds! if host || port
91
95
 
92
- if host && (host[0,1] == '.' || host[0,1] == '/')
93
- config.bind "unix://#{host}"
94
- elsif host && host =~ /^ssl:\/\//
95
- uri = URI.parse(host)
96
- uri.port ||= port || ::Puma::Configuration::DefaultTCPPort
97
- config.bind uri.to_s
98
- else
96
+ if host && (host[0,1] == '.' || host[0,1] == '/')
97
+ config.bind "unix://#{host}"
98
+ elsif host && host =~ /^ssl:\/\//
99
+ uri = URI.parse(host)
100
+ uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
101
+ config.bind uri.to_s
102
+ else
99
103
 
100
- if host
101
- port ||= ::Puma::Configuration::DefaultTCPPort
102
- end
104
+ if host
105
+ port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
106
+ end
103
107
 
104
- if port
105
- host ||= ::Puma::Configuration::DefaultTCPHost
106
- config.port port, host
107
- end
108
+ if port
109
+ host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
110
+ config.port port, host
108
111
  end
109
112
  end
110
113
  end
114
+ end
115
+ end
111
116
 
112
- register :puma, Puma
117
+ # rackup was removed in Rack 3, it is now a separate gem
118
+ if Object.const_defined? :Rackup
119
+ module Rackup
120
+ module Handler
121
+ module Puma
122
+ class << self
123
+ include ::Puma::RackHandler
124
+ end
125
+ end
126
+ register :puma, Puma
127
+ end
128
+ end
129
+ else
130
+ do_register = Object.const_defined?(:Rack) && Rack.release < '3'
131
+ module Rack
132
+ module Handler
133
+ module Puma
134
+ class << self
135
+ include ::Puma::RackHandler
136
+ end
137
+ end
138
+ end
113
139
  end
140
+ ::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
114
141
  end
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: 5.6.7
4
+ version: 6.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
@@ -62,6 +62,8 @@ files:
62
62
  - docs/signals.md
63
63
  - docs/stats.md
64
64
  - docs/systemd.md
65
+ - docs/testing_benchmarks_local_files.md
66
+ - docs/testing_test_rackup_ci_files.md
65
67
  - ext/puma_http11/PumaHttp11Service.java
66
68
  - ext/puma_http11/ext_help.h
67
69
  - ext/puma_http11/extconf.rb
@@ -96,26 +98,27 @@ files:
96
98
  - lib/puma/jruby_restart.rb
97
99
  - lib/puma/json_serialization.rb
98
100
  - lib/puma/launcher.rb
101
+ - lib/puma/launcher/bundle_pruner.rb
102
+ - lib/puma/log_writer.rb
99
103
  - lib/puma/minissl.rb
100
104
  - lib/puma/minissl/context_builder.rb
101
105
  - lib/puma/null_io.rb
102
106
  - lib/puma/plugin.rb
107
+ - lib/puma/plugin/systemd.rb
103
108
  - lib/puma/plugin/tmp_restart.rb
104
- - lib/puma/queue_close.rb
105
109
  - lib/puma/rack/builder.rb
106
110
  - lib/puma/rack/urlmap.rb
107
111
  - lib/puma/rack_default.rb
108
112
  - lib/puma/reactor.rb
109
113
  - lib/puma/request.rb
110
114
  - lib/puma/runner.rb
115
+ - lib/puma/sd_notify.rb
111
116
  - lib/puma/server.rb
112
117
  - lib/puma/single.rb
113
118
  - lib/puma/state_file.rb
114
- - lib/puma/systemd.rb
115
119
  - lib/puma/thread_pool.rb
116
120
  - lib/puma/util.rb
117
121
  - lib/rack/handler/puma.rb
118
- - lib/rack/version_restriction.rb
119
122
  - tools/Dockerfile
120
123
  - tools/trickletest.rb
121
124
  homepage: https://puma.io
@@ -126,6 +129,7 @@ metadata:
126
129
  changelog_uri: https://github.com/puma/puma/blob/master/History.md
127
130
  homepage_uri: https://puma.io
128
131
  source_code_uri: https://github.com/puma/puma
132
+ rubygems_mfa_required: 'true'
129
133
  post_install_message:
130
134
  rdoc_options: []
131
135
  require_paths:
@@ -134,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
138
  requirements:
135
139
  - - ">="
136
140
  - !ruby/object:Gem::Version
137
- version: '2.2'
141
+ version: '2.4'
138
142
  required_rubygems_version: !ruby/object:Gem::Requirement
139
143
  requirements:
140
144
  - - ">="
@@ -1,26 +0,0 @@
1
- class ClosedQueueError < StandardError; end
2
- module Puma
3
-
4
- # Queue#close was added in Ruby 2.3.
5
- # Add a simple implementation for earlier Ruby versions.
6
- #
7
- module QueueClose
8
- def close
9
- num_waiting.times {push nil}
10
- @closed = true
11
- end
12
- def closed?
13
- @closed ||= false
14
- end
15
- def push(object)
16
- raise ClosedQueueError if closed?
17
- super
18
- end
19
- alias << push
20
- def pop(non_block=false)
21
- return nil if !non_block && closed? && empty?
22
- super
23
- end
24
- end
25
- ::Queue.prepend QueueClose
26
- end
data/lib/puma/systemd.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'sd_notify'
4
-
5
- module Puma
6
- class Systemd
7
- def initialize(events)
8
- @events = events
9
- end
10
-
11
- def hook_events
12
- @events.on_booted { SdNotify.ready }
13
- @events.on_stopped { SdNotify.stopping }
14
- @events.on_restart { SdNotify.reloading }
15
- end
16
-
17
- def start_watchdog
18
- return unless SdNotify.watchdog?
19
-
20
- ping_f = watchdog_sleep_time
21
-
22
- log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
23
- Thread.new do
24
- loop do
25
- sleep ping_f
26
- SdNotify.watchdog
27
- end
28
- end
29
- end
30
-
31
- private
32
-
33
- def watchdog_sleep_time
34
- usec = Integer(ENV["WATCHDOG_USEC"])
35
-
36
- sec_f = usec / 1_000_000.0
37
- # "It is recommended that a daemon sends a keep-alive notification message
38
- # to the service manager every half of the time returned here."
39
- sec_f / 2
40
- end
41
-
42
- def log(str)
43
- @events.log str
44
- end
45
- end
46
- end
@@ -1,15 +0,0 @@
1
- begin
2
- begin
3
- # rack/version exists in Rack 2.2.0 and later, compatible with Ruby 2.3 and later
4
- # we prefer to not load Rack
5
- require 'rack/version'
6
- rescue LoadError
7
- require 'rack'
8
- end
9
-
10
- # Rack.release is needed for Rack v1, Rack::RELEASE was added in v2
11
- if Gem::Version.new(Rack.release) >= Gem::Version.new("3.0.0")
12
- raise StandardError.new "Puma 5 is not compatible with Rack 3, please upgrade to Puma 6 or higher."
13
- end
14
- rescue LoadError
15
- end