puma 4.3.6-java → 5.0.2-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 +1153 -518
- data/LICENSE +23 -20
- data/README.md +26 -13
- data/docs/architecture.md +3 -3
- data/docs/deployment.md +9 -3
- data/docs/fork_worker.md +31 -0
- data/docs/jungle/README.md +13 -0
- data/{tools → docs}/jungle/rc.d/README.md +0 -0
- data/{tools → docs}/jungle/rc.d/puma +0 -0
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/{tools → docs}/jungle/upstart/README.md +0 -0
- data/{tools → docs}/jungle/upstart/puma-manager.conf +0 -0
- data/{tools → docs}/jungle/upstart/puma.conf +0 -0
- data/docs/signals.md +7 -6
- data/docs/systemd.md +1 -63
- data/ext/puma_http11/PumaHttp11Service.java +2 -4
- data/ext/puma_http11/extconf.rb +4 -3
- data/ext/puma_http11/mini_ssl.c +15 -2
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +77 -18
- data/ext/puma_http11/puma_http11.c +6 -38
- data/lib/puma.rb +20 -0
- data/lib/puma/app/status.rb +14 -1
- data/lib/puma/binder.rb +90 -68
- data/lib/puma/cli.rb +7 -15
- data/lib/puma/client.rb +62 -13
- data/lib/puma/cluster.rb +193 -74
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/configuration.rb +31 -42
- data/lib/puma/const.rb +3 -3
- data/lib/puma/control_cli.rb +29 -17
- data/lib/puma/detect.rb +17 -0
- data/lib/puma/dsl.rb +144 -70
- data/lib/puma/error_logger.rb +97 -0
- data/lib/puma/events.rb +37 -31
- data/lib/puma/io_buffer.rb +9 -2
- data/lib/puma/jruby_restart.rb +0 -58
- data/lib/puma/launcher.rb +57 -31
- data/lib/puma/minissl.rb +68 -18
- data/lib/puma/minissl/context_builder.rb +0 -3
- data/lib/puma/null_io.rb +1 -1
- data/lib/puma/plugin.rb +1 -10
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +0 -4
- data/lib/puma/reactor.rb +10 -16
- data/lib/puma/runner.rb +8 -36
- data/lib/puma/server.rb +161 -218
- data/lib/puma/single.rb +8 -64
- data/lib/puma/state_file.rb +6 -3
- data/lib/puma/thread_pool.rb +116 -51
- data/lib/puma/util.rb +1 -0
- data/lib/rack/handler/puma.rb +1 -3
- data/tools/{docker/Dockerfile → Dockerfile} +0 -0
- metadata +17 -19
- data/docs/tcp_mode.md +0 -96
- data/ext/puma_http11/io_buffer.c +0 -155
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
- data/lib/puma/tcp_logger.rb +0 -41
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'puma/const'
|
4
|
+
|
5
|
+
module Puma
|
6
|
+
# The implementation of a detailed error logging.
|
7
|
+
# @version 5.0.0
|
8
|
+
#
|
9
|
+
class ErrorLogger
|
10
|
+
include Const
|
11
|
+
|
12
|
+
attr_reader :ioerr
|
13
|
+
|
14
|
+
REQUEST_FORMAT = %{"%s %s%s" - (%s)}
|
15
|
+
|
16
|
+
def initialize(ioerr)
|
17
|
+
@ioerr = ioerr
|
18
|
+
@ioerr.sync = true
|
19
|
+
|
20
|
+
@debug = ENV.key? 'PUMA_DEBUG'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.stdio
|
24
|
+
new $stderr
|
25
|
+
end
|
26
|
+
|
27
|
+
# Print occured error details.
|
28
|
+
# +options+ hash with additional options:
|
29
|
+
# - +error+ is an exception object
|
30
|
+
# - +req+ the http request
|
31
|
+
# - +text+ (default nil) custom string to print in title
|
32
|
+
# and before all remaining info.
|
33
|
+
#
|
34
|
+
def info(options={})
|
35
|
+
ioerr.puts title(options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Print occured error details only if
|
39
|
+
# environment variable PUMA_DEBUG is defined.
|
40
|
+
# +options+ hash with additional options:
|
41
|
+
# - +error+ is an exception object
|
42
|
+
# - +req+ the http request
|
43
|
+
# - +text+ (default nil) custom string to print in title
|
44
|
+
# and before all remaining info.
|
45
|
+
#
|
46
|
+
def debug(options={})
|
47
|
+
return unless @debug
|
48
|
+
|
49
|
+
error = options[:error]
|
50
|
+
req = options[:req]
|
51
|
+
|
52
|
+
string_block = []
|
53
|
+
string_block << title(options)
|
54
|
+
string_block << request_dump(req) if request_parsed?(req)
|
55
|
+
string_block << error.backtrace if error
|
56
|
+
|
57
|
+
ioerr.puts string_block.join("\n")
|
58
|
+
end
|
59
|
+
|
60
|
+
def title(options={})
|
61
|
+
text = options[:text]
|
62
|
+
req = options[:req]
|
63
|
+
error = options[:error]
|
64
|
+
|
65
|
+
string_block = ["#{Time.now}"]
|
66
|
+
string_block << " #{text}" if text
|
67
|
+
string_block << " (#{request_title(req)})" if request_parsed?(req)
|
68
|
+
string_block << ": #{error.inspect}" if error
|
69
|
+
string_block.join('')
|
70
|
+
end
|
71
|
+
|
72
|
+
def request_dump(req)
|
73
|
+
"Headers: #{request_headers(req)}\n" \
|
74
|
+
"Body: #{req.body}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def request_title(req)
|
78
|
+
env = req.env
|
79
|
+
|
80
|
+
REQUEST_FORMAT % [
|
81
|
+
env[REQUEST_METHOD],
|
82
|
+
env[REQUEST_PATH] || env[PATH_INFO],
|
83
|
+
env[QUERY_STRING] || "",
|
84
|
+
env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-"
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
88
|
+
def request_headers(req)
|
89
|
+
headers = req.env.select { |key, _| key.start_with?('HTTP_') }
|
90
|
+
headers.map { |key, value| [key[5..-1], value] }.to_h.inspect
|
91
|
+
end
|
92
|
+
|
93
|
+
def request_parsed?(req)
|
94
|
+
req && req.env[REQUEST_METHOD]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/puma/events.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'puma/const'
|
4
3
|
require "puma/null_io"
|
4
|
+
require 'puma/error_logger'
|
5
5
|
require 'stringio'
|
6
6
|
|
7
7
|
module Puma
|
@@ -23,8 +23,6 @@ module Puma
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
include Const
|
27
|
-
|
28
26
|
# Create an Events object that prints to +stdout+ and +stderr+.
|
29
27
|
#
|
30
28
|
def initialize(stdout, stderr)
|
@@ -36,6 +34,7 @@ module Puma
|
|
36
34
|
@stderr.sync = true
|
37
35
|
|
38
36
|
@debug = ENV.key? 'PUMA_DEBUG'
|
37
|
+
@error_logger = ErrorLogger.new(@stderr)
|
39
38
|
|
40
39
|
@hooks = Hash.new { |h,k| h[k] = [] }
|
41
40
|
end
|
@@ -66,7 +65,8 @@ module Puma
|
|
66
65
|
# Write +str+ to +@stdout+
|
67
66
|
#
|
68
67
|
def log(str)
|
69
|
-
@stdout.puts format(str)
|
68
|
+
@stdout.puts format(str) if @stdout.respond_to? :puts
|
69
|
+
rescue Errno::EPIPE
|
70
70
|
end
|
71
71
|
|
72
72
|
def write(str)
|
@@ -80,7 +80,7 @@ module Puma
|
|
80
80
|
# Write +str+ to +@stderr+
|
81
81
|
#
|
82
82
|
def error(str)
|
83
|
-
@
|
83
|
+
@error_logger.info(text: format("ERROR: #{str}"))
|
84
84
|
exit 1
|
85
85
|
end
|
86
86
|
|
@@ -88,43 +88,49 @@ module Puma
|
|
88
88
|
formatter.call(str)
|
89
89
|
end
|
90
90
|
|
91
|
+
# An HTTP connection error has occurred.
|
92
|
+
# +error+ a connection exception, +req+ the request,
|
93
|
+
# and +text+ additional info
|
94
|
+
# @version 5.0.0
|
95
|
+
#
|
96
|
+
def connection_error(error, req, text="HTTP connection error")
|
97
|
+
@error_logger.info(error: error, req: req, text: text)
|
98
|
+
end
|
99
|
+
|
91
100
|
# An HTTP parse error has occurred.
|
92
|
-
# +
|
93
|
-
#
|
101
|
+
# +error+ a parsing exception,
|
102
|
+
# and +req+ the request.
|
94
103
|
#
|
95
|
-
def parse_error(
|
96
|
-
@
|
97
|
-
"(#{env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR]}#{env[REQUEST_PATH]}): " \
|
98
|
-
"#{error.inspect}" \
|
99
|
-
"\n---\n"
|
104
|
+
def parse_error(error, req)
|
105
|
+
@error_logger.info(error: error, req: req, text: 'HTTP parse error, malformed request')
|
100
106
|
end
|
101
107
|
|
102
108
|
# An SSL error has occurred.
|
103
|
-
#
|
104
|
-
#
|
109
|
+
# @param error <Puma::MiniSSL::SSLError>
|
110
|
+
# @param ssl_socket <Puma::MiniSSL::Socket>
|
105
111
|
#
|
106
|
-
def ssl_error(
|
112
|
+
def ssl_error(error, ssl_socket)
|
113
|
+
peeraddr = ssl_socket.peeraddr.last rescue "<unknown>"
|
114
|
+
peercert = ssl_socket.peercert
|
107
115
|
subject = peercert ? peercert.subject : nil
|
108
|
-
@
|
116
|
+
@error_logger.info(error: error, text: "SSL error, peer: #{peeraddr}, peer cert: #{subject}")
|
109
117
|
end
|
110
118
|
|
111
119
|
# An unknown error has occurred.
|
112
|
-
# +
|
113
|
-
# +
|
120
|
+
# +error+ an exception object, +req+ the request,
|
121
|
+
# and +text+ additional info
|
114
122
|
#
|
115
|
-
def unknown_error(
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
@stderr.puts string_block.join("\n")
|
127
|
-
end
|
123
|
+
def unknown_error(error, req=nil, text="Unknown error")
|
124
|
+
@error_logger.info(error: error, req: req, text: text)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Log occurred error debug dump.
|
128
|
+
# +error+ an exception object, +req+ the request,
|
129
|
+
# and +text+ additional info
|
130
|
+
# @version 5.0.0
|
131
|
+
#
|
132
|
+
def debug_error(error, req=nil, text="")
|
133
|
+
@error_logger.debug(error: error, req: req, text: text)
|
128
134
|
end
|
129
135
|
|
130
136
|
def on_booted(&block)
|
data/lib/puma/io_buffer.rb
CHANGED
data/lib/puma/jruby_restart.rb
CHANGED
@@ -22,63 +22,5 @@ module Puma
|
|
22
22
|
execlp(cmd, *argv)
|
23
23
|
raise SystemCallError.new(FFI.errno)
|
24
24
|
end
|
25
|
-
|
26
|
-
PermKey = 'PUMA_DAEMON_PERM'
|
27
|
-
RestartKey = 'PUMA_DAEMON_RESTART'
|
28
|
-
|
29
|
-
# Called to tell things "Your now always in daemon mode,
|
30
|
-
# don't try to reenter it."
|
31
|
-
#
|
32
|
-
def self.perm_daemonize
|
33
|
-
ENV[PermKey] = "1"
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.daemon?
|
37
|
-
ENV.key?(PermKey) || ENV.key?(RestartKey)
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.daemon_init
|
41
|
-
return true if ENV.key?(PermKey)
|
42
|
-
|
43
|
-
return false unless ENV.key? RestartKey
|
44
|
-
|
45
|
-
master = ENV[RestartKey]
|
46
|
-
|
47
|
-
# In case the master disappears early
|
48
|
-
begin
|
49
|
-
Process.kill "SIGUSR2", master.to_i
|
50
|
-
rescue SystemCallError => e
|
51
|
-
end
|
52
|
-
|
53
|
-
ENV[RestartKey] = ""
|
54
|
-
|
55
|
-
setsid
|
56
|
-
|
57
|
-
null = File.open "/dev/null", "w+"
|
58
|
-
STDIN.reopen null
|
59
|
-
STDOUT.reopen null
|
60
|
-
STDERR.reopen null
|
61
|
-
|
62
|
-
true
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.daemon_start(dir, argv)
|
66
|
-
ENV[RestartKey] = Process.pid.to_s
|
67
|
-
|
68
|
-
if k = ENV['PUMA_JRUBY_DAEMON_OPTS']
|
69
|
-
ENV['JRUBY_OPTS'] = k
|
70
|
-
end
|
71
|
-
|
72
|
-
cmd = argv.first
|
73
|
-
argv = ([:string] * argv.size).zip(argv).flatten
|
74
|
-
argv << :string
|
75
|
-
argv << nil
|
76
|
-
|
77
|
-
chdir(dir)
|
78
|
-
ret = fork
|
79
|
-
return ret if ret != 0
|
80
|
-
execlp(cmd, *argv)
|
81
|
-
raise SystemCallError.new(FFI.errno)
|
82
|
-
end
|
83
25
|
end
|
84
26
|
end
|
data/lib/puma/launcher.rb
CHANGED
@@ -47,8 +47,9 @@ module Puma
|
|
47
47
|
@original_argv = @argv.dup
|
48
48
|
@config = conf
|
49
49
|
|
50
|
-
@binder = Binder.new(@events)
|
51
|
-
@binder.
|
50
|
+
@binder = Binder.new(@events, conf)
|
51
|
+
@binder.create_inherited_fds(ENV).each { |k| ENV.delete k }
|
52
|
+
@binder.create_activated_fds(ENV).each { |k| ENV.delete k }
|
52
53
|
|
53
54
|
@environment = conf.environment
|
54
55
|
|
@@ -69,10 +70,6 @@ module Puma
|
|
69
70
|
unsupported "worker mode not supported on #{RUBY_ENGINE} on this platform"
|
70
71
|
end
|
71
72
|
|
72
|
-
if @options[:daemon] && Puma.windows?
|
73
|
-
unsupported 'daemon mode not supported on Windows'
|
74
|
-
end
|
75
|
-
|
76
73
|
Dir.chdir(@restart_dir)
|
77
74
|
|
78
75
|
prune_bundler if prune_bundler?
|
@@ -105,6 +102,7 @@ module Puma
|
|
105
102
|
write_pid
|
106
103
|
|
107
104
|
path = @options[:state]
|
105
|
+
permission = @options[:state_permission]
|
108
106
|
return unless path
|
109
107
|
|
110
108
|
require 'puma/state_file'
|
@@ -113,8 +111,9 @@ module Puma
|
|
113
111
|
sf.pid = Process.pid
|
114
112
|
sf.control_url = @options[:control_url]
|
115
113
|
sf.control_auth_token = @options[:control_auth_token]
|
114
|
+
sf.running_from = File.expand_path('.')
|
116
115
|
|
117
|
-
sf.save path
|
116
|
+
sf.save path, permission
|
118
117
|
end
|
119
118
|
|
120
119
|
# Delete the configured pidfile
|
@@ -174,24 +173,28 @@ module Puma
|
|
174
173
|
case @status
|
175
174
|
when :halt
|
176
175
|
log "* Stopping immediately!"
|
176
|
+
@runner.stop_control
|
177
177
|
when :run, :stop
|
178
178
|
graceful_stop
|
179
179
|
when :restart
|
180
180
|
log "* Restarting..."
|
181
181
|
ENV.replace(previous_env)
|
182
|
-
@runner.
|
182
|
+
@runner.stop_control
|
183
183
|
restart!
|
184
184
|
when :exit
|
185
185
|
# nothing
|
186
186
|
end
|
187
|
-
@
|
187
|
+
close_binder_listeners unless @status == :restart
|
188
188
|
end
|
189
189
|
|
190
|
-
# Return
|
191
|
-
|
192
|
-
|
190
|
+
# Return all tcp ports the launcher may be using, TCP or SSL
|
191
|
+
# @!attribute [r] connected_ports
|
192
|
+
# @version 5.0.0
|
193
|
+
def connected_ports
|
194
|
+
@binder.connected_ports
|
193
195
|
end
|
194
196
|
|
197
|
+
# @!attribute [r] restart_args
|
195
198
|
def restart_args
|
196
199
|
cmd = @options[:restart_cmd]
|
197
200
|
if cmd
|
@@ -202,9 +205,23 @@ module Puma
|
|
202
205
|
end
|
203
206
|
|
204
207
|
def close_binder_listeners
|
208
|
+
@runner.close_control_listeners
|
205
209
|
@binder.close_listeners
|
206
210
|
end
|
207
211
|
|
212
|
+
# @!attribute [r] thread_status
|
213
|
+
# @version 5.0.0
|
214
|
+
def thread_status
|
215
|
+
Thread.list.each do |thread|
|
216
|
+
name = "Thread: TID-#{thread.object_id.to_s(36)}"
|
217
|
+
name += " #{thread['label']}" if thread['label']
|
218
|
+
name += " #{thread.name}" if thread.respond_to?(:name) && thread.name
|
219
|
+
backtrace = thread.backtrace || ["<no backtrace available>"]
|
220
|
+
|
221
|
+
yield name, backtrace
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
208
225
|
private
|
209
226
|
|
210
227
|
# If configured, write the pid of the current process out
|
@@ -225,7 +242,7 @@ module Puma
|
|
225
242
|
end
|
226
243
|
|
227
244
|
def restart!
|
228
|
-
@config.run_hooks :on_restart, self
|
245
|
+
@config.run_hooks :on_restart, self, @events
|
229
246
|
|
230
247
|
if Puma.jruby?
|
231
248
|
close_binder_listeners
|
@@ -241,11 +258,13 @@ module Puma
|
|
241
258
|
else
|
242
259
|
argv = restart_args
|
243
260
|
Dir.chdir(@restart_dir)
|
261
|
+
ENV.update(@binder.redirects_for_restart_env)
|
244
262
|
argv += [@binder.redirects_for_restart]
|
245
263
|
Kernel.exec(*argv)
|
246
264
|
end
|
247
265
|
end
|
248
266
|
|
267
|
+
# @!attribute [r] dependencies_and_files_to_require_after_prune
|
249
268
|
def dependencies_and_files_to_require_after_prune
|
250
269
|
puma = spec_for_gem("puma")
|
251
270
|
|
@@ -256,6 +275,7 @@ module Puma
|
|
256
275
|
[deps, require_paths_for_gem(puma) + extra_runtime_deps_directories]
|
257
276
|
end
|
258
277
|
|
278
|
+
# @!attribute [r] extra_runtime_deps_directories
|
259
279
|
def extra_runtime_deps_directories
|
260
280
|
Array(@options[:extra_runtime_dependencies]).map do |d_name|
|
261
281
|
if (spec = spec_for_gem(d_name))
|
@@ -267,6 +287,7 @@ module Puma
|
|
267
287
|
end.flatten.compact
|
268
288
|
end
|
269
289
|
|
290
|
+
# @!attribute [r] puma_wild_location
|
270
291
|
def puma_wild_location
|
271
292
|
puma = spec_for_gem("puma")
|
272
293
|
dirs = require_paths_for_gem(puma)
|
@@ -275,6 +296,7 @@ module Puma
|
|
275
296
|
end
|
276
297
|
|
277
298
|
def prune_bundler
|
299
|
+
return if ENV['PUMA_BUNDLER_PRUNED']
|
278
300
|
return unless defined?(Bundler)
|
279
301
|
require_rubygems_min_version!(Gem::Version.new("2.2"), "prune_bundler")
|
280
302
|
unless puma_wild_location
|
@@ -286,8 +308,10 @@ module Puma
|
|
286
308
|
|
287
309
|
log '* Pruning Bundler environment'
|
288
310
|
home = ENV['GEM_HOME']
|
289
|
-
Bundler.
|
311
|
+
bundle_gemfile = Bundler.original_env['BUNDLE_GEMFILE']
|
312
|
+
with_unbundled_env do
|
290
313
|
ENV['GEM_HOME'] = home
|
314
|
+
ENV['BUNDLE_GEMFILE'] = bundle_gemfile
|
291
315
|
ENV['PUMA_BUNDLER_PRUNED'] = '1'
|
292
316
|
args = [Gem.ruby, puma_wild_location, '-I', dirs.join(':'), deps.join(',')] + @original_argv
|
293
317
|
# Ruby 2.0+ defaults to true which breaks socket activation
|
@@ -323,25 +347,11 @@ module Puma
|
|
323
347
|
log "- Goodbye!"
|
324
348
|
end
|
325
349
|
|
326
|
-
def log_thread_status
|
327
|
-
Thread.list.each do |thread|
|
328
|
-
log "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
|
329
|
-
logstr = "Thread: TID-#{thread.object_id.to_s(36)}"
|
330
|
-
logstr += " #{thread.name}" if thread.respond_to?(:name)
|
331
|
-
log logstr
|
332
|
-
|
333
|
-
if thread.backtrace
|
334
|
-
log thread.backtrace.join("\n")
|
335
|
-
else
|
336
|
-
log "<no backtrace available>"
|
337
|
-
end
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
350
|
def set_process_title
|
342
351
|
Process.respond_to?(:setproctitle) ? Process.setproctitle(title) : $0 = title
|
343
352
|
end
|
344
353
|
|
354
|
+
# @!attribute [r] title
|
345
355
|
def title
|
346
356
|
buffer = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})"
|
347
357
|
buffer += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
|
@@ -353,6 +363,7 @@ module Puma
|
|
353
363
|
ENV['RACK_ENV'] = environment
|
354
364
|
end
|
355
365
|
|
366
|
+
# @!attribute [r] environment
|
356
367
|
def environment
|
357
368
|
@environment
|
358
369
|
end
|
@@ -456,8 +467,13 @@ module Puma
|
|
456
467
|
end
|
457
468
|
|
458
469
|
begin
|
459
|
-
|
460
|
-
|
470
|
+
unless Puma.jruby? # INFO in use by JVM already
|
471
|
+
Signal.trap "SIGINFO" do
|
472
|
+
thread_status do |name, backtrace|
|
473
|
+
@events.log name
|
474
|
+
@events.log backtrace.map { |bt| " #{bt}" }
|
475
|
+
end
|
476
|
+
end
|
461
477
|
end
|
462
478
|
rescue Exception
|
463
479
|
# Not going to log this one, as SIGINFO is *BSD only and would be pretty annoying
|
@@ -471,5 +487,15 @@ module Puma
|
|
471
487
|
raise "#{feature} is not supported on your version of RubyGems. " \
|
472
488
|
"You must have RubyGems #{min_version}+ to use this feature."
|
473
489
|
end
|
490
|
+
|
491
|
+
# @version 5.0.0
|
492
|
+
def with_unbundled_env
|
493
|
+
bundler_ver = Gem::Version.new(Bundler::VERSION)
|
494
|
+
if bundler_ver < Gem::Version.new('2.1.0')
|
495
|
+
Bundler.with_clean_env { yield }
|
496
|
+
else
|
497
|
+
Bundler.with_unbundled_env { yield }
|
498
|
+
end
|
499
|
+
end
|
474
500
|
end
|
475
501
|
end
|