ed-precompiled_puma 7.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +3172 -0
  3. data/LICENSE +29 -0
  4. data/README.md +477 -0
  5. data/bin/puma +10 -0
  6. data/bin/puma-wild +25 -0
  7. data/bin/pumactl +12 -0
  8. data/docs/architecture.md +74 -0
  9. data/docs/compile_options.md +55 -0
  10. data/docs/deployment.md +102 -0
  11. data/docs/fork_worker.md +41 -0
  12. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  13. data/docs/images/puma-connection-flow.png +0 -0
  14. data/docs/images/puma-general-arch.png +0 -0
  15. data/docs/java_options.md +54 -0
  16. data/docs/jungle/README.md +9 -0
  17. data/docs/jungle/rc.d/README.md +74 -0
  18. data/docs/jungle/rc.d/puma +61 -0
  19. data/docs/jungle/rc.d/puma.conf +10 -0
  20. data/docs/kubernetes.md +80 -0
  21. data/docs/nginx.md +80 -0
  22. data/docs/plugins.md +42 -0
  23. data/docs/rails_dev_mode.md +28 -0
  24. data/docs/restart.md +65 -0
  25. data/docs/signals.md +98 -0
  26. data/docs/stats.md +148 -0
  27. data/docs/systemd.md +253 -0
  28. data/docs/testing_benchmarks_local_files.md +150 -0
  29. data/docs/testing_test_rackup_ci_files.md +36 -0
  30. data/ext/puma_http11/PumaHttp11Service.java +17 -0
  31. data/ext/puma_http11/ext_help.h +15 -0
  32. data/ext/puma_http11/extconf.rb +65 -0
  33. data/ext/puma_http11/http11_parser.c +1057 -0
  34. data/ext/puma_http11/http11_parser.h +65 -0
  35. data/ext/puma_http11/http11_parser.java.rl +145 -0
  36. data/ext/puma_http11/http11_parser.rl +149 -0
  37. data/ext/puma_http11/http11_parser_common.rl +54 -0
  38. data/ext/puma_http11/mini_ssl.c +852 -0
  39. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  40. data/ext/puma_http11/org/jruby/puma/Http11.java +257 -0
  41. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +455 -0
  42. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +509 -0
  43. data/ext/puma_http11/puma_http11.c +507 -0
  44. data/lib/puma/app/status.rb +96 -0
  45. data/lib/puma/binder.rb +511 -0
  46. data/lib/puma/cli.rb +245 -0
  47. data/lib/puma/client.rb +720 -0
  48. data/lib/puma/cluster/worker.rb +182 -0
  49. data/lib/puma/cluster/worker_handle.rb +127 -0
  50. data/lib/puma/cluster.rb +635 -0
  51. data/lib/puma/cluster_accept_loop_delay.rb +91 -0
  52. data/lib/puma/commonlogger.rb +115 -0
  53. data/lib/puma/configuration.rb +452 -0
  54. data/lib/puma/const.rb +307 -0
  55. data/lib/puma/control_cli.rb +320 -0
  56. data/lib/puma/detect.rb +47 -0
  57. data/lib/puma/dsl.rb +1480 -0
  58. data/lib/puma/error_logger.rb +115 -0
  59. data/lib/puma/events.rb +72 -0
  60. data/lib/puma/io_buffer.rb +50 -0
  61. data/lib/puma/jruby_restart.rb +11 -0
  62. data/lib/puma/json_serialization.rb +96 -0
  63. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  64. data/lib/puma/launcher.rb +496 -0
  65. data/lib/puma/log_writer.rb +147 -0
  66. data/lib/puma/minissl/context_builder.rb +96 -0
  67. data/lib/puma/minissl.rb +463 -0
  68. data/lib/puma/null_io.rb +101 -0
  69. data/lib/puma/plugin/systemd.rb +90 -0
  70. data/lib/puma/plugin/tmp_restart.rb +36 -0
  71. data/lib/puma/plugin.rb +111 -0
  72. data/lib/puma/rack/builder.rb +297 -0
  73. data/lib/puma/rack/urlmap.rb +93 -0
  74. data/lib/puma/rack_default.rb +24 -0
  75. data/lib/puma/reactor.rb +140 -0
  76. data/lib/puma/request.rb +701 -0
  77. data/lib/puma/runner.rb +211 -0
  78. data/lib/puma/sd_notify.rb +146 -0
  79. data/lib/puma/server.rb +734 -0
  80. data/lib/puma/single.rb +72 -0
  81. data/lib/puma/state_file.rb +69 -0
  82. data/lib/puma/thread_pool.rb +402 -0
  83. data/lib/puma/util.rb +134 -0
  84. data/lib/puma.rb +93 -0
  85. data/lib/rack/handler/puma.rb +144 -0
  86. data/tools/Dockerfile +18 -0
  87. data/tools/trickletest.rb +44 -0
  88. metadata +152 -0
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'server'
4
+ require_relative 'const'
5
+
6
+ module Puma
7
+ # Generic class that is used by `Puma::Cluster` and `Puma::Single` to
8
+ # serve requests. This class spawns a new instance of `Puma::Server` via
9
+ # a call to `start_server`.
10
+ class Runner
11
+
12
+ include ::Puma::Const::PipeRequest
13
+
14
+ def initialize(launcher)
15
+ @launcher = launcher
16
+ @log_writer = launcher.log_writer
17
+ @events = launcher.events
18
+ @config = launcher.config
19
+ @options = launcher.options
20
+ @app = nil
21
+ @control = nil
22
+ @started_at = Time.now
23
+ @wakeup = nil
24
+ end
25
+
26
+ # Returns the hash of configuration options.
27
+ # @return [Puma::UserFileDefaultOptions]
28
+ attr_reader :options
29
+
30
+ def wakeup!
31
+ return unless @wakeup
32
+
33
+ @wakeup.write PIPE_WAKEUP unless @wakeup.closed?
34
+
35
+ rescue SystemCallError, IOError
36
+ end
37
+
38
+ def development?
39
+ @options[:environment] == "development"
40
+ end
41
+
42
+ def test?
43
+ @options[:environment] == "test"
44
+ end
45
+
46
+ def log(str)
47
+ @log_writer.log str
48
+ end
49
+
50
+ # @version 5.0.0
51
+ def stop_control
52
+ @control&.stop true
53
+ end
54
+
55
+ def error(str)
56
+ @log_writer.error str
57
+ end
58
+
59
+ def debug(str)
60
+ @log_writer.log "- #{str}" if @options[:debug]
61
+ end
62
+
63
+ def start_control
64
+ str = @options[:control_url]
65
+ return unless str
66
+
67
+ require_relative 'app/status'
68
+
69
+ if token = @options[:control_auth_token]
70
+ token = nil if token.empty? || token == 'none'
71
+ end
72
+
73
+ app = Puma::App::Status.new @launcher, token
74
+
75
+ # A Reactor is not created and nio4r is not loaded when 'queue_requests: false'
76
+ # Use `nil` for events, no hooks in control server
77
+ control = Puma::Server.new app, nil,
78
+ { min_threads: 0, max_threads: 1, queue_requests: false, log_writer: @log_writer }
79
+
80
+ begin
81
+ control.binder.parse [str], nil, 'Starting control server'
82
+ rescue Errno::EADDRINUSE, Errno::EACCES => e
83
+ raise e, "Error: Control server address '#{str}' is already in use. Original error: #{e.message}"
84
+ end
85
+
86
+ control.run thread_name: 'ctl'
87
+ @control = control
88
+ end
89
+
90
+ # @version 5.0.0
91
+ def close_control_listeners
92
+ @control.binder.close_listeners if @control
93
+ end
94
+
95
+ def output_header(mode)
96
+ min_t = @options[:min_threads]
97
+ max_t = @options[:max_threads]
98
+ environment = @options[:environment]
99
+
100
+ log "Puma starting in #{mode} mode..."
101
+ log "* Puma version: #{Puma::Const::PUMA_VERSION} (\"#{Puma::Const::CODE_NAME}\")"
102
+ log "* Ruby version: #{RUBY_DESCRIPTION}"
103
+ log "* Min threads: #{min_t}"
104
+ log "* Max threads: #{max_t}"
105
+ log "* Environment: #{environment}"
106
+
107
+ if mode == "cluster"
108
+ log "* Master PID: #{Process.pid}"
109
+ else
110
+ log "* PID: #{Process.pid}"
111
+ end
112
+ end
113
+
114
+ def warn_ruby_mn_threads
115
+ return if !ENV.key?('RUBY_MN_THREADS')
116
+
117
+ log "! WARNING: Detected `RUBY_MN_THREADS=#{ENV['RUBY_MN_THREADS']}`"
118
+ log "! This setting is known to cause performance regressions with Puma."
119
+ log "! Consider disabling this environment variable: https://github.com/puma/puma/issues/3720"
120
+ end
121
+
122
+ def redirected_io?
123
+ @options[:redirect_stdout] || @options[:redirect_stderr]
124
+ end
125
+
126
+ def redirect_io
127
+ stdout = @options[:redirect_stdout]
128
+ stderr = @options[:redirect_stderr]
129
+ append = @options[:redirect_append]
130
+
131
+ if stdout
132
+ ensure_output_directory_exists(stdout, 'STDOUT')
133
+
134
+ STDOUT.reopen stdout, (append ? "a" : "w")
135
+ STDOUT.puts "=== puma startup: #{Time.now} ==="
136
+ STDOUT.flush unless STDOUT.sync
137
+ end
138
+
139
+ if stderr
140
+ ensure_output_directory_exists(stderr, 'STDERR')
141
+
142
+ STDERR.reopen stderr, (append ? "a" : "w")
143
+ STDERR.puts "=== puma startup: #{Time.now} ==="
144
+ STDERR.flush unless STDERR.sync
145
+ end
146
+
147
+ if @options[:mutate_stdout_and_stderr_to_sync_on_write]
148
+ STDOUT.sync = true
149
+ STDERR.sync = true
150
+ end
151
+ end
152
+
153
+ def load_and_bind
154
+ unless @config.app_configured?
155
+ error "No application configured, nothing to run"
156
+ exit 1
157
+ end
158
+
159
+ begin
160
+ @app = @config.app
161
+ rescue Exception => e
162
+ log "! Unable to load application: #{e.class}: #{e.message}"
163
+ raise e
164
+ end
165
+
166
+ @launcher.binder.parse @options[:binds]
167
+ end
168
+
169
+ # @!attribute [r] app
170
+ def app
171
+ @app ||= @config.app
172
+ end
173
+
174
+ def start_server
175
+ server = Puma::Server.new(app, @events, @options)
176
+ server.inherit_binder(@launcher.binder)
177
+ server
178
+ end
179
+
180
+ private
181
+ def ensure_output_directory_exists(path, io_name)
182
+ unless Dir.exist?(File.dirname(path))
183
+ raise "Cannot redirect #{io_name} to #{path}"
184
+ end
185
+ end
186
+
187
+ def utc_iso8601(val)
188
+ "#{val.utc.strftime '%FT%T'}Z"
189
+ end
190
+
191
+ def stats
192
+ {
193
+ versions: {
194
+ puma: Puma::Const::PUMA_VERSION,
195
+ ruby: {
196
+ engine: RUBY_ENGINE,
197
+ version: RUBY_VERSION,
198
+ patchlevel: RUBY_PATCHLEVEL
199
+ }
200
+ }
201
+ }
202
+ end
203
+
204
+ # this method call should always be guarded by `@log_writer.debug?`
205
+ def debug_loaded_extensions(str)
206
+ @log_writer.debug "────────────────────────────────── #{str}"
207
+ re_ext = /\.#{RbConfig::CONFIG['DLEXT']}\z/i
208
+ $LOADED_FEATURES.grep(re_ext).each { |f| @log_writer.debug(" #{f}") }
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Puma
6
+ # The MIT License
7
+ #
8
+ # Copyright (c) 2017-2022 Agis Anastasopoulos
9
+ #
10
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
11
+ # this software and associated documentation files (the "Software"), to deal in
12
+ # the Software without restriction, including without limitation the rights to
13
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14
+ # the Software, and to permit persons to whom the Software is furnished to do so,
15
+ # subject to the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be included in all
18
+ # copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
22
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
23
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #
27
+ # This is a copy of https://github.com/agis/ruby-sdnotify as of commit cca575c
28
+ # The only changes made was "rehoming" it within the Puma module to avoid
29
+ # namespace collisions and applying standard's code formatting style.
30
+ #
31
+ # SdNotify is a pure-Ruby implementation of sd_notify(3). It can be used to
32
+ # notify systemd about state changes. Methods of this package are no-op on
33
+ # non-systemd systems (eg. Darwin).
34
+ #
35
+ # The API maps closely to the original implementation of sd_notify(3),
36
+ # therefore be sure to check the official man pages prior to using SdNotify.
37
+ #
38
+ # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html
39
+ module SdNotify
40
+ # Exception raised when there's an error writing to the notification socket
41
+ class NotifyError < RuntimeError; end
42
+
43
+ READY = "READY=1"
44
+ RELOADING = "RELOADING=1"
45
+ STOPPING = "STOPPING=1"
46
+ STATUS = "STATUS="
47
+ ERRNO = "ERRNO="
48
+ MAINPID = "MAINPID="
49
+ WATCHDOG = "WATCHDOG=1"
50
+ FDSTORE = "FDSTORE=1"
51
+
52
+ def self.ready(unset_env=false)
53
+ notify(READY, unset_env)
54
+ end
55
+
56
+ def self.reloading(unset_env=false)
57
+ notify(RELOADING, unset_env)
58
+ end
59
+
60
+ def self.stopping(unset_env=false)
61
+ notify(STOPPING, unset_env)
62
+ end
63
+
64
+ # @param status [String] a custom status string that describes the current
65
+ # state of the service
66
+ def self.status(status, unset_env=false)
67
+ notify("#{STATUS}#{status}", unset_env)
68
+ end
69
+
70
+ # @param errno [Integer]
71
+ def self.errno(errno, unset_env=false)
72
+ notify("#{ERRNO}#{errno}", unset_env)
73
+ end
74
+
75
+ # @param pid [Integer]
76
+ def self.mainpid(pid, unset_env=false)
77
+ notify("#{MAINPID}#{pid}", unset_env)
78
+ end
79
+
80
+ def self.watchdog(unset_env=false)
81
+ notify(WATCHDOG, unset_env)
82
+ end
83
+
84
+ def self.fdstore(unset_env=false)
85
+ notify(FDSTORE, unset_env)
86
+ end
87
+
88
+ # @param [Boolean] true if the service manager expects watchdog keep-alive
89
+ # notification messages to be sent from this process.
90
+ #
91
+ # If the $WATCHDOG_USEC environment variable is set,
92
+ # and the $WATCHDOG_PID variable is unset or set to the PID of the current
93
+ # process
94
+ #
95
+ # @note Unlike sd_watchdog_enabled(3), this method does not mutate the
96
+ # environment.
97
+ def self.watchdog?
98
+ wd_usec = ENV["WATCHDOG_USEC"]
99
+ wd_pid = ENV["WATCHDOG_PID"]
100
+
101
+ return false if !wd_usec
102
+
103
+ begin
104
+ wd_usec = Integer(wd_usec)
105
+ rescue
106
+ return false
107
+ end
108
+
109
+ return false if wd_usec <= 0
110
+ return true if !wd_pid || wd_pid == $$.to_s
111
+
112
+ false
113
+ end
114
+
115
+ # Notify systemd with the provided state, via the notification socket, if
116
+ # any.
117
+ #
118
+ # Generally this method will be used indirectly through the other methods
119
+ # of the library.
120
+ #
121
+ # @param state [String]
122
+ # @param unset_env [Boolean]
123
+ #
124
+ # @return [Fixnum, nil] the number of bytes written to the notification
125
+ # socket or nil if there was no socket to report to (eg. the program wasn't
126
+ # started by systemd)
127
+ #
128
+ # @raise [NotifyError] if there was an error communicating with the systemd
129
+ # socket
130
+ #
131
+ # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html
132
+ def self.notify(state, unset_env=false)
133
+ sock = ENV["NOTIFY_SOCKET"]
134
+
135
+ return nil if !sock
136
+
137
+ ENV.delete("NOTIFY_SOCKET") if unset_env
138
+
139
+ begin
140
+ Addrinfo.unix(sock, :DGRAM).connect { |s| s.write state }
141
+ rescue StandardError => e
142
+ raise NotifyError, "#{e.class}: #{e.message}", e.backtrace
143
+ end
144
+ end
145
+ end
146
+ end