puma 2.16.0 → 3.11.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 (78) hide show
  1. checksums.yaml +5 -5
  2. data/{History.txt → History.md} +489 -70
  3. data/README.md +143 -174
  4. data/docs/architecture.md +36 -0
  5. data/{DEPLOYMENT.md → docs/deployment.md} +1 -1
  6. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  7. data/docs/images/puma-connection-flow.png +0 -0
  8. data/docs/images/puma-general-arch.png +0 -0
  9. data/docs/nginx.md +2 -2
  10. data/docs/plugins.md +28 -0
  11. data/docs/restart.md +39 -0
  12. data/docs/signals.md +56 -3
  13. data/docs/systemd.md +272 -0
  14. data/ext/puma_http11/extconf.rb +2 -0
  15. data/ext/puma_http11/http11_parser.c +291 -447
  16. data/ext/puma_http11/http11_parser.h +1 -0
  17. data/ext/puma_http11/http11_parser.java.rl +5 -5
  18. data/ext/puma_http11/http11_parser.rl +10 -9
  19. data/ext/puma_http11/http11_parser_common.rl +1 -1
  20. data/ext/puma_http11/io_buffer.c +8 -8
  21. data/ext/puma_http11/mini_ssl.c +64 -6
  22. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +113 -131
  23. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +9 -2
  24. data/ext/puma_http11/puma_http11.c +1 -0
  25. data/lib/puma/app/status.rb +9 -1
  26. data/lib/puma/binder.rb +90 -38
  27. data/lib/puma/cli.rb +134 -491
  28. data/lib/puma/client.rb +142 -4
  29. data/lib/puma/cluster.rb +132 -76
  30. data/lib/puma/commonlogger.rb +19 -20
  31. data/lib/puma/compat.rb +3 -7
  32. data/lib/puma/configuration.rb +206 -67
  33. data/lib/puma/const.rb +21 -31
  34. data/lib/puma/control_cli.rb +92 -103
  35. data/lib/puma/convenient.rb +23 -0
  36. data/lib/puma/daemon_ext.rb +6 -0
  37. data/lib/puma/detect.rb +10 -1
  38. data/lib/puma/dsl.rb +203 -45
  39. data/lib/puma/events.rb +22 -13
  40. data/lib/puma/io_buffer.rb +1 -1
  41. data/lib/puma/jruby_restart.rb +1 -2
  42. data/lib/puma/launcher.rb +431 -0
  43. data/lib/puma/minissl.rb +83 -4
  44. data/lib/puma/null_io.rb +19 -11
  45. data/lib/puma/plugin/tmp_restart.rb +34 -0
  46. data/lib/puma/plugin.rb +115 -0
  47. data/lib/puma/rack/backports/uri/common_193.rb +17 -13
  48. data/lib/puma/rack/builder.rb +3 -0
  49. data/lib/puma/rack/urlmap.rb +9 -8
  50. data/lib/puma/reactor.rb +18 -0
  51. data/lib/puma/runner.rb +43 -15
  52. data/lib/puma/server.rb +141 -35
  53. data/lib/puma/single.rb +16 -6
  54. data/lib/puma/state_file.rb +29 -0
  55. data/lib/puma/tcp_logger.rb +8 -1
  56. data/lib/puma/thread_pool.rb +60 -10
  57. data/lib/puma/util.rb +1 -5
  58. data/lib/puma.rb +13 -4
  59. data/lib/rack/handler/puma.rb +76 -29
  60. data/tools/jungle/README.md +12 -2
  61. data/tools/jungle/init.d/README.md +9 -2
  62. data/tools/jungle/init.d/puma +86 -59
  63. data/tools/jungle/init.d/run-puma +16 -1
  64. data/tools/jungle/rc.d/README.md +74 -0
  65. data/tools/jungle/rc.d/puma +61 -0
  66. data/tools/jungle/rc.d/puma.conf +10 -0
  67. data/tools/jungle/upstart/puma.conf +1 -1
  68. data/tools/trickletest.rb +1 -1
  69. metadata +28 -95
  70. data/COPYING +0 -55
  71. data/Gemfile +0 -13
  72. data/Manifest.txt +0 -74
  73. data/Rakefile +0 -158
  74. data/docs/config.md +0 -0
  75. data/lib/puma/capistrano.rb +0 -94
  76. data/lib/puma/rack/backports/uri/common_18.rb +0 -56
  77. data/lib/puma/rack/backports/uri/common_192.rb +0 -52
  78. data/puma.gemspec +0 -52
data/lib/puma/cli.rb CHANGED
@@ -1,17 +1,11 @@
1
1
  require 'optparse'
2
2
  require 'uri'
3
3
 
4
- require 'puma/server'
5
- require 'puma/const'
4
+ require 'puma'
6
5
  require 'puma/configuration'
7
- require 'puma/binder'
8
- require 'puma/detect'
9
- require 'puma/daemon_ext'
10
- require 'puma/util'
11
- require 'puma/single'
12
- require 'puma/cluster'
13
-
14
- require 'puma/commonlogger'
6
+ require 'puma/launcher'
7
+ require 'puma/const'
8
+ require 'puma/events'
15
9
 
16
10
  module Puma
17
11
  class << self
@@ -25,11 +19,7 @@ module Puma
25
19
  # Handles invoke a Puma::Server in a command line style.
26
20
  #
27
21
  class CLI
28
- KEYS_NOT_TO_PERSIST_IN_STATE = [
29
- :logger, :lowlevel_error_handler,
30
- :before_worker_shutdown, :before_worker_boot, :before_worker_fork,
31
- :after_worker_boot, :before_fork, :on_restart
32
- ]
22
+ KEYS_NOT_TO_PERSIST_IN_STATE = Launcher::KEYS_NOT_TO_PERSIST_IN_STATE
33
23
 
34
24
  # Create a new CLI object using +argv+ as the command line
35
25
  # arguments.
@@ -39,544 +29,197 @@ module Puma
39
29
  #
40
30
  def initialize(argv, events=Events.stdio)
41
31
  @debug = false
42
- @argv = argv
32
+ @argv = argv.dup
43
33
 
44
34
  @events = events
45
35
 
46
- @status = nil
47
- @runner = nil
48
-
49
- @config = nil
36
+ @conf = nil
50
37
 
51
- setup_options
52
- generate_restart_data
53
-
54
- @binder = Binder.new(@events)
55
- @binder.import_from_env
56
- end
38
+ @stdout = nil
39
+ @stderr = nil
40
+ @append = false
57
41
 
58
- # The Binder object containing the sockets bound to.
59
- attr_reader :binder
60
-
61
- # The Configuration object used.
62
- attr_reader :config
63
-
64
- # The Hash of options used to configure puma.
65
- attr_reader :options
66
-
67
- # The Events object used to output information.
68
- attr_reader :events
69
-
70
- # Delegate +log+ to +@events+
71
- #
72
- def log(str)
73
- @events.log str
74
- end
42
+ @control_url = nil
43
+ @control_options = {}
75
44
 
76
- # Delegate +error+ to +@events+
77
- #
78
- def error(str)
79
- @events.error str
80
- end
81
-
82
- def debug(str)
83
- @events.log "- #{str}" if @options[:debug]
84
- end
85
-
86
- def clustered?
87
- @options[:workers] > 0
88
- end
89
-
90
- def prune_bundler?
91
- @options[:prune_bundler] && clustered? && !@options[:preload_app]
92
- end
93
-
94
- def jruby?
95
- IS_JRUBY
96
- end
97
-
98
- def windows?
99
- RUBY_PLATFORM =~ /mswin32|ming32/
100
- end
101
-
102
- def env
103
- @options[:environment] || @cli_options[:environment] || ENV['RACK_ENV'] || 'development'
104
- end
105
-
106
- def write_state
107
- write_pid
108
-
109
- path = @options[:state]
110
- return unless path
111
-
112
- state = { 'pid' => Process.pid }
113
- cfg = @config.dup
114
-
115
- KEYS_NOT_TO_PERSIST_IN_STATE.each { |k| cfg.options.delete(k) }
116
- state['config'] = cfg
117
-
118
- require 'yaml'
119
- File.open(path, 'w') { |f| f.write state.to_yaml }
120
- end
121
-
122
- # If configured, write the pid of the current process out
123
- # to a file.
124
- #
125
- def write_pid
126
- path = @options[:pidfile]
127
- return unless path
128
-
129
- File.open(path, 'w') { |f| f.puts Process.pid }
130
- cur = Process.pid
131
- at_exit do
132
- delete_pidfile if cur == Process.pid
133
- end
134
- end
135
-
136
- def delete_pidfile
137
- path = @options[:pidfile]
138
- File.unlink(path) if path && File.exist?(path)
139
- end
140
-
141
- def graceful_stop
142
- @runner.stop_blocked
143
- log "=== puma shutdown: #{Time.now} ==="
144
- log "- Goodbye!"
145
- end
146
-
147
- def jruby_daemon_start
148
- require 'puma/jruby_restart'
149
- JRubyRestart.daemon_start(@restart_dir, restart_args)
150
- end
45
+ setup_options
151
46
 
152
- def restart!
153
- @options[:on_restart].each do |block|
154
- block.call self
155
- end
47
+ begin
48
+ @parser.parse! @argv
156
49
 
157
- if jruby?
158
- close_binder_listeners
159
-
160
- require 'puma/jruby_restart'
161
- JRubyRestart.chdir_exec(@restart_dir, restart_args)
162
- elsif windows?
163
- close_binder_listeners
164
-
165
- argv = restart_args
166
- Dir.chdir(@restart_dir)
167
- argv += [redirects] if RUBY_VERSION >= '1.9'
168
- Kernel.exec(*argv)
169
- else
170
- redirects = {:close_others => true}
171
- @binder.listeners.each_with_index do |(l, io), i|
172
- ENV["PUMA_INHERIT_#{i}"] = "#{io.to_i}:#{l}"
173
- redirects[io.to_i] = io.to_i
50
+ if file = @argv.shift
51
+ @conf.configure do |user_config, file_config|
52
+ file_config.rackup file
53
+ end
174
54
  end
175
-
176
- argv = restart_args
177
- Dir.chdir(@restart_dir)
178
- argv += [redirects] if RUBY_VERSION >= '1.9'
179
- Kernel.exec(*argv)
180
- end
181
- end
182
-
183
- # Parse the options, load the rackup, start the server and wait
184
- # for it to finish.
185
- #
186
- def run
187
- begin
188
- parse_options
189
55
  rescue UnsupportedOption
190
56
  exit 1
191
57
  end
192
58
 
193
- dir = @options[:directory]
194
- Dir.chdir(dir) if dir
195
-
196
- prune_bundler if prune_bundler?
197
-
198
- set_rack_environment
199
-
200
- if clustered?
201
- @events.formatter = Events::PidFormatter.new
202
- @options[:logger] = @events
203
-
204
- @runner = Cluster.new(self)
205
- else
206
- @runner = Single.new(self)
207
- end
208
-
209
- setup_signals
210
- set_process_title
211
-
212
- @status = :run
213
-
214
- @runner.run
215
-
216
- case @status
217
- when :halt
218
- log "* Stopping immediately!"
219
- when :run, :stop
220
- graceful_stop
221
- when :restart
222
- log "* Restarting..."
223
- @runner.before_restart
224
- restart!
225
- when :exit
226
- # nothing
227
- end
228
- end
229
-
230
- def stop
231
- @status = :stop
232
- @runner.stop
233
- end
234
-
235
- def restart
236
- @status = :restart
237
- @runner.restart
238
- end
239
-
240
- def reload_worker_directory
241
- @runner.reload_worker_directory if @runner.respond_to?(:reload_worker_directory)
242
- end
59
+ @conf.configure do |user_config, file_config|
60
+ if @stdout || @stderr
61
+ user_config.stdout_redirect @stdout, @stderr, @append
62
+ end
243
63
 
244
- def phased_restart
245
- unless @runner.respond_to?(:phased_restart) and @runner.phased_restart
246
- log "* phased-restart called but not available, restarting normally."
247
- return restart
64
+ if @control_url
65
+ user_config.activate_control_app @control_url, @control_options
66
+ end
248
67
  end
249
- true
250
- end
251
68
 
252
- def redirect_io
253
- @runner.redirect_io
69
+ @launcher = Puma::Launcher.new(@conf, :events => @events, :argv => argv)
254
70
  end
255
71
 
256
- def stats
257
- @runner.stats
258
- end
72
+ attr_reader :launcher
259
73
 
260
- def halt
261
- @status = :halt
262
- @runner.halt
74
+ # Parse the options, load the rackup, start the server and wait
75
+ # for it to finish.
76
+ #
77
+ def run
78
+ @launcher.run
263
79
  end
264
80
 
265
81
  private
266
- def title
267
- buffer = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})"
268
- buffer << " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
269
- buffer
270
- end
271
-
272
82
  def unsupported(str)
273
83
  @events.error(str)
274
84
  raise UnsupportedOption
275
85
  end
276
86
 
277
- def restart_args
278
- cmd = @options[:restart_cmd]
279
- if cmd
280
- cmd.split(' ') + @original_argv
281
- else
282
- @restart_argv
283
- end
284
- end
285
-
286
- def set_process_title
287
- Process.respond_to?(:setproctitle) ? Process.setproctitle(title) : $0 = title
288
- end
289
-
290
- def find_config
291
- if @cli_options[:config_file] == '-'
292
- @cli_options[:config_file] = nil
293
- else
294
- @cli_options[:config_file] ||= %W(config/puma/#{env}.rb config/puma.rb).find { |f| File.exist?(f) }
295
- end
296
- end
297
-
298
87
  # Build the OptionParser object to handle the available options.
299
88
  #
300
89
 
301
90
  def setup_options
302
- @cli_options = {}
303
- @options = {}
304
-
305
- @parser = OptionParser.new do |o|
306
- o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
307
- (@cli_options[:binds] ||= []) << arg
308
- end
309
-
310
- o.on "-C", "--config PATH", "Load PATH as a config file" do |arg|
311
- @cli_options[:config_file] = arg
312
- end
313
-
314
- o.on "--control URL", "The bind url to use for the control server",
315
- "Use 'auto' to use temp unix server" do |arg|
316
- if arg
317
- @cli_options[:control_url] = arg
318
- elsif jruby?
319
- unsupported "No default url available on JRuby"
91
+ @conf = Configuration.new do |user_config, file_config|
92
+ @parser = OptionParser.new do |o|
93
+ o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
94
+ user_config.bind arg
320
95
  end
321
- end
322
-
323
- o.on "--control-token TOKEN",
324
- "The token to use as authentication for the control server" do |arg|
325
- @cli_options[:control_auth_token] = arg
326
- end
327
-
328
- o.on "-d", "--daemon", "Daemonize the server into the background" do
329
- @cli_options[:daemon] = true
330
- @cli_options[:quiet] = true
331
- end
332
-
333
- o.on "--debug", "Log lowlevel debugging information" do
334
- @cli_options[:debug] = true
335
- end
336
-
337
- o.on "--dir DIR", "Change to DIR before starting" do |d|
338
- @cli_options[:directory] = d.to_s
339
- @cli_options[:worker_directory] = d.to_s
340
- end
341
-
342
- o.on "-e", "--environment ENVIRONMENT",
343
- "The environment to run the Rack app on (default development)" do |arg|
344
- @cli_options[:environment] = arg
345
- end
346
-
347
- o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg|
348
- $LOAD_PATH.unshift(*arg.split(':'))
349
- end
350
-
351
- o.on "-p", "--port PORT", "Define the TCP port to bind to",
352
- "Use -b for more advanced options" do |arg|
353
- binds = (@cli_options[:binds] ||= [])
354
- binds << "tcp://#{Configuration::DefaultTCPHost}:#{arg}"
355
- end
356
96
 
357
- o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg|
358
- @cli_options[:pidfile] = arg
359
- end
360
-
361
- o.on "--preload", "Preload the app. Cluster mode only" do
362
- @cli_options[:preload_app] = true
363
- end
364
-
365
- o.on "--prune-bundler", "Prune out the bundler env if possible" do
366
- @cli_options[:prune_bundler] = true
367
- end
97
+ o.on "-C", "--config PATH", "Load PATH as a config file" do |arg|
98
+ file_config.load arg
99
+ end
368
100
 
369
- o.on "-q", "--quiet", "Quiet down the output" do
370
- @cli_options[:quiet] = true
371
- end
101
+ o.on "--control URL", "The bind url to use for the control server",
102
+ "Use 'auto' to use temp unix server" do |arg|
103
+ if arg
104
+ @control_url = arg
105
+ elsif Puma.jruby?
106
+ unsupported "No default url available on JRuby"
107
+ end
108
+ end
372
109
 
373
- o.on "-R", "--restart-cmd CMD",
374
- "The puma command to run during a hot restart",
375
- "Default: inferred" do |cmd|
376
- @cli_options[:restart_cmd] = cmd
377
- end
110
+ o.on "--control-token TOKEN",
111
+ "The token to use as authentication for the control server" do |arg|
112
+ @control_options[:auth_token] = arg
113
+ end
378
114
 
379
- o.on "-S", "--state PATH", "Where to store the state details" do |arg|
380
- @cli_options[:state] = arg
381
- end
115
+ o.on "-d", "--daemon", "Daemonize the server into the background" do
116
+ user_config.daemonize
117
+ user_config.quiet
118
+ end
382
119
 
383
- o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
384
- min, max = arg.split(":")
385
- if max
386
- @cli_options[:min_threads] = min
387
- @cli_options[:max_threads] = max
388
- else
389
- @cli_options[:min_threads] = 0
390
- @cli_options[:max_threads] = arg
120
+ o.on "--debug", "Log lowlevel debugging information" do
121
+ user_config.debug
391
122
  end
392
- end
393
123
 
394
- o.on "--tcp-mode", "Run the app in raw TCP mode instead of HTTP mode" do
395
- @cli_options[:mode] = :tcp
396
- end
124
+ o.on "--dir DIR", "Change to DIR before starting" do |d|
125
+ user_config.directory d
126
+ end
397
127
 
398
- o.on "-V", "--version", "Print the version information" do
399
- puts "puma version #{Puma::Const::VERSION}"
400
- exit 0
401
- end
128
+ o.on "-e", "--environment ENVIRONMENT",
129
+ "The environment to run the Rack app on (default development)" do |arg|
130
+ user_config.environment arg
131
+ end
402
132
 
403
- o.on "-w", "--workers COUNT",
404
- "Activate cluster mode: How many worker processes to create" do |arg|
405
- @cli_options[:workers] = arg.to_i
406
- end
133
+ o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg|
134
+ $LOAD_PATH.unshift(*arg.split(':'))
135
+ end
407
136
 
408
- o.on "--tag NAME", "Additional text to display in process listing" do |arg|
409
- @cli_options[:tag] = arg
410
- end
137
+ o.on "-p", "--port PORT", "Define the TCP port to bind to",
138
+ "Use -b for more advanced options" do |arg|
139
+ user_config.bind "tcp://#{Configuration::DefaultTCPHost}:#{arg}"
140
+ end
411
141
 
412
- o.on "--redirect-stdout FILE", "Redirect STDOUT to a specific file" do |arg|
413
- @cli_options[:redirect_stdout] = arg
414
- end
142
+ o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg|
143
+ user_config.pidfile arg
144
+ end
415
145
 
416
- o.on "--redirect-stderr FILE", "Redirect STDERR to a specific file" do |arg|
417
- @cli_options[:redirect_stderr] = arg
418
- end
146
+ o.on "--preload", "Preload the app. Cluster mode only" do
147
+ user_config.preload_app!
148
+ end
419
149
 
420
- o.on "--[no-]redirect-append", "Append to redirected files" do |val|
421
- @cli_options[:redirect_append] = val
422
- end
150
+ o.on "--prune-bundler", "Prune out the bundler env if possible" do
151
+ user_config.prune_bundler
152
+ end
423
153
 
424
- o.banner = "puma <options> <rackup file>"
154
+ o.on "-q", "--quiet", "Do not log requests internally (default true)" do
155
+ user_config.quiet
156
+ end
425
157
 
426
- o.on_tail "-h", "--help", "Show help" do
427
- log o
428
- exit 0
429
- end
430
- end
431
- end
158
+ o.on "-v", "--log-requests", "Log requests as they occur" do
159
+ user_config.log_requests
160
+ end
432
161
 
433
- def generate_restart_data
434
- # Use the same trick as unicorn, namely favor PWD because
435
- # it will contain an unresolved symlink, useful for when
436
- # the pwd is /data/releases/current.
437
- if dir = ENV['PWD']
438
- s_env = File.stat(dir)
439
- s_pwd = File.stat(Dir.pwd)
440
-
441
- if s_env.ino == s_pwd.ino and (jruby? or s_env.dev == s_pwd.dev)
442
- @restart_dir = dir
443
- @options[:worker_directory] = dir
444
- end
445
- end
162
+ o.on "-R", "--restart-cmd CMD",
163
+ "The puma command to run during a hot restart",
164
+ "Default: inferred" do |cmd|
165
+ user_config.restart_command cmd
166
+ end
446
167
 
447
- @restart_dir ||= Dir.pwd
168
+ o.on "-S", "--state PATH", "Where to store the state details" do |arg|
169
+ user_config.state_path arg
170
+ end
448
171
 
449
- @original_argv = @argv.dup
172
+ o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
173
+ min, max = arg.split(":")
174
+ if max
175
+ user_config.threads min, max
176
+ else
177
+ user_config.threads min, min
178
+ end
179
+ end
450
180
 
451
- require 'rubygems'
181
+ o.on "--tcp-mode", "Run the app in raw TCP mode instead of HTTP mode" do
182
+ user_config.tcp_mode!
183
+ end
452
184
 
453
- # if $0 is a file in the current directory, then restart
454
- # it the same, otherwise add -S on there because it was
455
- # picked up in PATH.
456
- #
457
- if File.exist?($0)
458
- arg0 = [Gem.ruby, $0]
459
- else
460
- arg0 = [Gem.ruby, "-S", $0]
461
- end
185
+ o.on "--early-hints", "Enable early hints support" do
186
+ user_config.early_hints
187
+ end
462
188
 
463
- # Detect and reinject -Ilib from the command line
464
- lib = File.expand_path "lib"
465
- arg0[1,0] = ["-I", lib] if $:[0] == lib
189
+ o.on "-V", "--version", "Print the version information" do
190
+ puts "puma version #{Puma::Const::VERSION}"
191
+ exit 0
192
+ end
466
193
 
467
- if defined? Puma::WILD_ARGS
468
- @restart_argv = arg0 + Puma::WILD_ARGS + @original_argv
469
- else
470
- @restart_argv = arg0 + @original_argv
471
- end
472
- end
194
+ o.on "-w", "--workers COUNT",
195
+ "Activate cluster mode: How many worker processes to create" do |arg|
196
+ user_config.workers arg
197
+ end
473
198
 
474
- def set_rack_environment
475
- @options[:environment] = env
476
- ENV['RACK_ENV'] = env
477
- end
199
+ o.on "--tag NAME", "Additional text to display in process listing" do |arg|
200
+ user_config.tag arg
201
+ end
478
202
 
479
- def setup_signals
480
- begin
481
- Signal.trap "SIGUSR2" do
482
- restart
483
- end
484
- rescue Exception
485
- log "*** SIGUSR2 not implemented, signal based restart unavailable!"
486
- end
203
+ o.on "--redirect-stdout FILE", "Redirect STDOUT to a specific file" do |arg|
204
+ @stdout = arg.to_s
205
+ end
487
206
 
488
- begin
489
- Signal.trap "SIGUSR1" do
490
- phased_restart
491
- end
492
- rescue Exception
493
- log "*** SIGUSR1 not implemented, signal based restart unavailable!"
494
- end
207
+ o.on "--redirect-stderr FILE", "Redirect STDERR to a specific file" do |arg|
208
+ @stderr = arg.to_s
209
+ end
495
210
 
496
- begin
497
- Signal.trap "SIGTERM" do
498
- stop
499
- end
500
- rescue Exception
501
- log "*** SIGTERM not implemented, signal based gracefully stopping unavailable!"
502
- end
211
+ o.on "--[no-]redirect-append", "Append to redirected files" do |val|
212
+ @append = val
213
+ end
503
214
 
504
- begin
505
- Signal.trap "SIGHUP" do
506
- redirect_io
507
- end
508
- rescue Exception
509
- log "*** SIGHUP not implemented, signal based logs reopening unavailable!"
510
- end
215
+ o.banner = "puma <options> <rackup file>"
511
216
 
512
- if jruby?
513
- Signal.trap("INT") do
514
- @status = :exit
515
- graceful_stop
516
- exit
217
+ o.on_tail "-h", "--help", "Show help" do
218
+ $stdout.puts o
219
+ exit 0
220
+ end
517
221
  end
518
222
  end
519
223
  end
520
-
521
- def close_binder_listeners
522
- @binder.listeners.each do |l, io|
523
- io.close
524
- uri = URI.parse(l)
525
- next unless uri.scheme == 'unix'
526
- File.unlink("#{uri.host}#{uri.path}")
527
- end
528
- end
529
-
530
- def parse_options
531
- @parser.parse! @argv
532
-
533
- @cli_options[:rackup] = @argv.shift if @argv.last
534
-
535
- find_config
536
-
537
- @config = Puma::Configuration.new @cli_options
538
-
539
- # Advertise the Configuration
540
- Puma.cli_config = @config
541
-
542
- @config.load
543
-
544
- @options = @config.options
545
-
546
- if clustered? && (jruby? || windows?)
547
- unsupported 'worker mode not supported on JRuby or Windows'
548
- end
549
-
550
- if @options[:daemon] && windows?
551
- unsupported 'daemon mode not supported on Windows'
552
- end
553
- end
554
-
555
- def prune_bundler
556
- return unless defined?(Bundler)
557
- puma = Bundler.rubygems.loaded_specs("puma")
558
- dirs = puma.require_paths.map { |x| File.join(puma.full_gem_path, x) }
559
- puma_lib_dir = dirs.detect { |x| File.exist? File.join(x, '../bin/puma-wild') }
560
-
561
- unless puma_lib_dir
562
- log "! Unable to prune Bundler environment, continuing"
563
- return
564
- end
565
-
566
- deps = puma.runtime_dependencies.map do |d|
567
- spec = Bundler.rubygems.loaded_specs(d.name)
568
- "#{d.name}:#{spec.version.to_s}"
569
- end
570
-
571
- log '* Pruning Bundler environment'
572
- home = ENV['GEM_HOME']
573
- Bundler.with_clean_env do
574
- ENV['GEM_HOME'] = home
575
- ENV['PUMA_BUNDLER_PRUNED'] = '1'
576
- wild = File.expand_path(File.join(puma_lib_dir, "../bin/puma-wild"))
577
- args = [Gem.ruby, wild, '-I', dirs.join(':'), deps.join(',')] + @original_argv
578
- Kernel.exec(*args)
579
- end
580
- end
581
224
  end
582
225
  end