puma 6.4.3 → 8.0.2

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +448 -8
  3. data/README.md +110 -51
  4. data/docs/5.0-Upgrade.md +98 -0
  5. data/docs/6.0-Upgrade.md +56 -0
  6. data/docs/7.0-Upgrade.md +52 -0
  7. data/docs/8.0-Upgrade.md +100 -0
  8. data/docs/deployment.md +58 -23
  9. data/docs/fork_worker.md +11 -1
  10. data/docs/grpc.md +62 -0
  11. data/docs/images/favicon.svg +1 -0
  12. data/docs/images/running-puma.svg +1 -0
  13. data/docs/images/standard-logo.svg +1 -0
  14. data/docs/java_options.md +54 -0
  15. data/docs/jungle/README.md +1 -1
  16. data/docs/kubernetes.md +11 -16
  17. data/docs/plugins.md +6 -2
  18. data/docs/restart.md +2 -2
  19. data/docs/signals.md +21 -21
  20. data/docs/stats.md +11 -5
  21. data/docs/systemd.md +14 -5
  22. data/ext/puma_http11/extconf.rb +20 -32
  23. data/ext/puma_http11/http11_parser.java.rl +51 -65
  24. data/ext/puma_http11/mini_ssl.c +29 -9
  25. data/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
  26. data/ext/puma_http11/org/jruby/puma/Http11.java +194 -101
  27. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +71 -85
  28. data/ext/puma_http11/puma_http11.c +125 -118
  29. data/lib/puma/app/status.rb +11 -3
  30. data/lib/puma/binder.rb +22 -12
  31. data/lib/puma/cli.rb +11 -9
  32. data/lib/puma/client.rb +233 -136
  33. data/lib/puma/client_env.rb +171 -0
  34. data/lib/puma/cluster/worker.rb +24 -21
  35. data/lib/puma/cluster/worker_handle.rb +38 -8
  36. data/lib/puma/cluster.rb +74 -48
  37. data/lib/puma/cluster_accept_loop_delay.rb +91 -0
  38. data/lib/puma/commonlogger.rb +3 -3
  39. data/lib/puma/configuration.rb +197 -64
  40. data/lib/puma/const.rb +23 -12
  41. data/lib/puma/control_cli.rb +11 -7
  42. data/lib/puma/detect.rb +13 -0
  43. data/lib/puma/dsl.rb +483 -127
  44. data/lib/puma/error_logger.rb +7 -5
  45. data/lib/puma/events.rb +25 -10
  46. data/lib/puma/io_buffer.rb +8 -4
  47. data/lib/puma/jruby_restart.rb +0 -16
  48. data/lib/puma/launcher/bundle_pruner.rb +3 -5
  49. data/lib/puma/launcher.rb +76 -59
  50. data/lib/puma/log_writer.rb +17 -11
  51. data/lib/puma/minissl/context_builder.rb +1 -0
  52. data/lib/puma/minissl.rb +1 -1
  53. data/lib/puma/null_io.rb +26 -0
  54. data/lib/puma/plugin/systemd.rb +3 -3
  55. data/lib/puma/rack/urlmap.rb +1 -1
  56. data/lib/puma/reactor.rb +19 -13
  57. data/lib/puma/{request.rb → response.rb} +57 -209
  58. data/lib/puma/runner.rb +15 -17
  59. data/lib/puma/sd_notify.rb +1 -4
  60. data/lib/puma/server.rb +200 -104
  61. data/lib/puma/server_plugin_control.rb +32 -0
  62. data/lib/puma/single.rb +7 -4
  63. data/lib/puma/state_file.rb +3 -2
  64. data/lib/puma/thread_pool.rb +179 -96
  65. data/lib/puma/util.rb +0 -7
  66. data/lib/puma.rb +10 -0
  67. data/lib/rack/handler/puma.rb +11 -8
  68. data/tools/Dockerfile +15 -5
  69. metadata +26 -16
  70. data/ext/puma_http11/ext_help.h +0 -15
data/lib/puma/dsl.rb CHANGED
@@ -13,7 +13,7 @@ module Puma
13
13
  # config = Configuration.new({}) do |user_config|
14
14
  # user_config.port 3001
15
15
  # end
16
- # config.load
16
+ # config.clamp
17
17
  #
18
18
  # puts config.options[:binds] # => "tcp://127.0.0.1:3001"
19
19
  #
@@ -25,7 +25,7 @@ module Puma
25
25
  # Resulting configuration:
26
26
  #
27
27
  # config = Configuration.new(config_file: "puma_config.rb")
28
- # config.load
28
+ # config.clamp
29
29
  #
30
30
  # puts config.options[:binds] # => "tcp://127.0.0.1:3002"
31
31
  #
@@ -43,15 +43,17 @@ module Puma
43
43
  #
44
44
  # The following hooks have been updated:
45
45
  #
46
- # | DSL Method | Options Key | Fork Block Location |
47
- # | on_worker_boot | :before_worker_boot | inside, before |
48
- # | on_worker_shutdown | :before_worker_shutdown | inside, after |
49
- # | on_refork | :before_refork | inside |
46
+ # | DSL Method | Options Key | Fork Block Location |
47
+ # | before_worker_boot | :before_worker_boot | inside, before |
48
+ # | before_worker_shutdown | :before_worker_shutdown | inside, after |
49
+ # | before_refork | :before_refork | inside |
50
+ # | after_refork | :after_refork | inside |
50
51
  #
51
52
  class DSL
52
53
  ON_WORKER_KEY = [String, Symbol].freeze
53
54
 
54
- # convenience method so logic can be used in CI
55
+ # Convenience method so logic can be used in CI.
56
+ #
55
57
  # @see ssl_bind
56
58
  #
57
59
  def self.ssl_bind_str(host, port, opts)
@@ -85,6 +87,7 @@ module Puma
85
87
  "&verify_mode=#{verify}#{tls_str}#{ca_additions}#{backlog_str}"
86
88
  else
87
89
  ssl_cipher_filter = opts[:ssl_cipher_filter] ? "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil
90
+ ssl_ciphersuites = opts[:ssl_ciphersuites] ? "&ssl_ciphersuites=#{opts[:ssl_ciphersuites]}" : nil
88
91
  v_flags = (ary = opts[:verification_flags]) ? "&verification_flags=#{Array(ary).join ','}" : nil
89
92
 
90
93
  cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(cert)}" : nil
@@ -115,7 +118,7 @@ module Puma
115
118
  nil
116
119
  end
117
120
 
118
- "ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{password_flags}#{ssl_cipher_filter}" \
121
+ "ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{password_flags}#{ssl_cipher_filter}#{ssl_ciphersuites}" \
119
122
  "#{reuse_flag}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}#{low_latency_str}"
120
123
  end
121
124
  end
@@ -152,7 +155,7 @@ module Puma
152
155
  end
153
156
 
154
157
  def default_host
155
- @options[:default_host] || Configuration::DEFAULTS[:tcp_host]
158
+ @options[:default_host] || Configuration.default_tcp_host
156
159
  end
157
160
 
158
161
  def inject(&blk)
@@ -163,7 +166,10 @@ module Puma
163
166
  @options[key.to_sym] || default
164
167
  end
165
168
 
166
- # Load the named plugin for use by this configuration
169
+ # Load the named plugin for use by this configuration.
170
+ #
171
+ # @example
172
+ # plugin :tmp_restart
167
173
  #
168
174
  def plugin(name)
169
175
  @plugins << @config.load_plugin(name)
@@ -210,6 +216,9 @@ module Puma
210
216
  # activate_control_app 'unix:///var/run/pumactl.sock', { auth_token: '12345' }
211
217
  # @example
212
218
  # activate_control_app 'unix:///var/run/pumactl.sock', { no_token: true }
219
+ # @example
220
+ # activate_control_app 'unix:///var/run/pumactl.sock', { no_token: true, data_only: true}
221
+ #
213
222
  def activate_control_app(url="auto", opts={})
214
223
  if url == "auto"
215
224
  path = Configuration.temp_path
@@ -233,10 +242,15 @@ module Puma
233
242
 
234
243
  @options[:control_auth_token] = auth_token
235
244
  @options[:control_url_umask] = opts[:umask] if opts[:umask]
245
+ @options[:control_data_only] = opts[:data_only] if opts[:data_only]
236
246
  end
237
247
 
238
- # Load additional configuration from a file
239
- # Files get loaded later via Configuration#load
248
+ # Load additional configuration from a file.
249
+ # Files get loaded later via Configuration#load.
250
+ #
251
+ # @example
252
+ # load 'config/puma/production.rb'
253
+ #
240
254
  def load(file)
241
255
  @options[:config_files] ||= []
242
256
  @options[:config_files] << file
@@ -246,7 +260,8 @@ module Puma
246
260
  # accepted protocols. Multiple urls can be bound to, calling +bind+ does
247
261
  # not overwrite previous bindings.
248
262
  #
249
- # The default is "tcp://0.0.0.0:9292".
263
+ # The default is "tcp://[::]:9292" when IPv6 interfaces are available,
264
+ # otherwise "tcp://0.0.0.0:9292".
250
265
  #
251
266
  # You can use query parameters within the url to specify options:
252
267
  #
@@ -265,9 +280,10 @@ module Puma
265
280
  # @example SSL cert for mutual TLS (mTLS)
266
281
  # bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem&ca=ca.pem&verify_mode=force_peer'
267
282
  # @example Disable optimization for low latency
268
- # bind 'tcp://0.0.0.0:9292?low_latency=false'
283
+ # bind 'tcp://[::]:9292?low_latency=false'
269
284
  # @example Socket permissions
270
285
  # bind 'unix:///var/run/puma.sock?umask=0111'
286
+ #
271
287
  # @see Puma::Runner#load_and_bind
272
288
  # @see Puma::Cluster#run
273
289
  #
@@ -302,46 +318,81 @@ module Puma
302
318
  #
303
319
  # @example Only bind to systemd activated sockets, ignoring other binds
304
320
  # bind_to_activated_sockets 'only'
321
+ #
305
322
  def bind_to_activated_sockets(bind=true)
306
323
  @options[:bind_to_activated_sockets] = bind
307
324
  end
308
325
 
309
- # Define the TCP port to bind to. Use +bind+ for more advanced options.
326
+ # Define the TCP port to bind to. Use `bind` for more advanced options.
327
+ #
328
+ # The default is +9292+.
310
329
  #
311
330
  # @example
312
- # port 9292
331
+ # port 3000
332
+ #
313
333
  def port(port, host=nil)
314
334
  host ||= default_host
315
335
  bind URI::Generic.build(scheme: 'tcp', host: host, port: Integer(port)).to_s
316
336
  end
317
337
 
318
338
  # Define how long the tcp socket stays open, if no data has been received.
339
+ #
340
+ # The default is 30 seconds.
341
+ #
342
+ # @example
343
+ # first_data_timeout 40
344
+ #
319
345
  # @see Puma::Server.new
346
+ #
320
347
  def first_data_timeout(seconds)
321
348
  @options[:first_data_timeout] = Integer(seconds)
322
349
  end
323
350
 
324
351
  # Define how long persistent connections can be idle before Puma closes them.
352
+ #
353
+ # The default is 65 seconds.
354
+ #
355
+ # @example
356
+ # persistent_timeout 30
357
+ #
325
358
  # @see Puma::Server.new
359
+ #
326
360
  def persistent_timeout(seconds)
327
361
  @options[:persistent_timeout] = Integer(seconds)
328
362
  end
329
363
 
330
364
  # If a new request is not received within this number of seconds, begin shutting down.
365
+ #
366
+ # The default is +nil+.
367
+ #
368
+ # @example
369
+ # idle_timeout 60
370
+ #
331
371
  # @see Puma::Server.new
372
+ #
332
373
  def idle_timeout(seconds)
333
374
  @options[:idle_timeout] = Integer(seconds)
334
375
  end
335
376
 
336
- # Work around leaky apps that leave garbage in Thread locals
337
- # across requests.
338
- def clean_thread_locals(which=true)
339
- @options[:clean_thread_locals] = which
377
+ # Use a clean fiber per request which ensures a clean slate for fiber
378
+ # locals and fiber storage. Also provides a cleaner backtrace with less
379
+ # Puma internal stack frames.
380
+ #
381
+ # The default is +false+.
382
+ #
383
+ # @example
384
+ # fiber_per_request
385
+ #
386
+ def fiber_per_request(which=true)
387
+ @options[:fiber_per_request] = which
340
388
  end
341
389
 
390
+ alias clean_thread_locals fiber_per_request
391
+
342
392
  # When shutting down, drain the accept socket of pending connections and
343
393
  # process them. This loops over the accept socket until there are no more
344
394
  # read events and then stops looking and waits for the requests to finish.
395
+ #
345
396
  # @see Puma::Server#graceful_shutdown
346
397
  #
347
398
  def drain_on_shutdown(which=true)
@@ -355,18 +406,22 @@ module Puma
355
406
  #
356
407
  # @example
357
408
  # environment 'production'
409
+ #
358
410
  def environment(environment)
359
411
  @options[:environment] = environment
360
412
  end
361
413
 
362
- # How long to wait for threads to stop when shutting them
363
- # down. Defaults to :forever. Specifying :immediately will cause
364
- # Puma to kill the threads immediately. Otherwise the value
365
- # is the number of seconds to wait.
414
+ # How long to wait for threads to stop when shutting them down.
415
+ # Specifying :immediately will cause Puma to kill the threads immediately.
416
+ # Otherwise the value is the number of seconds to wait.
366
417
  #
367
418
  # Puma always waits a few seconds after killing a thread for it to try
368
419
  # to finish up it's work, even in :immediately mode.
420
+ #
421
+ # The default is +:forever+.
422
+ #
369
423
  # @see Puma::Server#graceful_shutdown
424
+ #
370
425
  def force_shutdown_after(val=:forever)
371
426
  i = case val
372
427
  when :forever
@@ -386,20 +441,25 @@ module Puma
386
441
  # This can be called multiple times to add code each time.
387
442
  #
388
443
  # @example
389
- # on_restart do
444
+ # before_restart do
390
445
  # puts 'On restart...'
391
446
  # end
392
- def on_restart(&block)
393
- @options[:on_restart] ||= []
394
- @options[:on_restart] << block
447
+ #
448
+ def before_restart(&block)
449
+ Puma.deprecate_method_change :on_restart, __callee__, __method__
450
+
451
+ process_hook :before_restart, nil, block
395
452
  end
396
453
 
454
+ alias_method :on_restart, :before_restart
455
+
397
456
  # Command to use to restart Puma. This should be just how to
398
457
  # load Puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
399
458
  # to Puma, as those are the same as the original process.
400
459
  #
401
460
  # @example
402
461
  # restart_command '/u/app/lolcat/bin/restart_puma'
462
+ #
403
463
  def restart_command(cmd)
404
464
  @options[:restart_cmd] = cmd.to_s
405
465
  end
@@ -408,31 +468,49 @@ module Puma
408
468
  #
409
469
  # @example
410
470
  # pidfile '/u/apps/lolcat/tmp/pids/puma.pid'
471
+ #
411
472
  def pidfile(path)
412
473
  @options[:pidfile] = path.to_s
413
474
  end
414
475
 
415
- # Disable request logging, if this isn't used it'll be enabled by default.
476
+ # Disable request logging, the inverse of `log_requests`.
477
+ #
478
+ # The default is +true+.
416
479
  #
417
480
  # @example
418
481
  # quiet
482
+ #
419
483
  def quiet(which=true)
420
484
  @options[:log_requests] = !which
421
485
  end
422
486
 
423
- # Enable request logging
487
+ # Enable request logging, the inverse of `quiet`.
488
+ #
489
+ # The default is +false+.
490
+ #
491
+ # @example
492
+ # log_requests
424
493
  #
425
494
  def log_requests(which=true)
426
495
  @options[:log_requests] = which
427
496
  end
428
497
 
429
498
  # Pass in a custom logging class instance
499
+ #
500
+ # @example
501
+ # custom_logger Logger.new('t.log')
502
+ #
430
503
  def custom_logger(custom_logger)
431
504
  @options[:custom_logger] = custom_logger
432
505
  end
433
506
 
434
507
  # Show debugging info
435
508
  #
509
+ # The default is +false+.
510
+ #
511
+ # @example
512
+ # debug
513
+ #
436
514
  def debug
437
515
  @options[:debug] = true
438
516
  end
@@ -443,6 +521,7 @@ module Puma
443
521
  #
444
522
  # @example
445
523
  # rackup '/u/apps/lolcat/config.ru'
524
+ #
446
525
  def rackup(path)
447
526
  @options[:rackup] ||= path.to_s
448
527
  end
@@ -450,21 +529,32 @@ module Puma
450
529
  # Allows setting `env['rack.url_scheme']`.
451
530
  # Only necessary if X-Forwarded-Proto is not being set by your proxy
452
531
  # Normal values are 'http' or 'https'.
532
+ #
453
533
  def rack_url_scheme(scheme=nil)
454
534
  @options[:rack_url_scheme] = scheme
455
535
  end
456
536
 
537
+ # Enable HTTP 103 Early Hints responses.
538
+ #
539
+ # The default is +nil+.
540
+ #
541
+ # @example
542
+ # early_hints
543
+ #
457
544
  def early_hints(answer=true)
458
545
  @options[:early_hints] = answer
459
546
  end
460
547
 
461
548
  # Redirect +STDOUT+ and +STDERR+ to files specified. The +append+ parameter
462
- # specifies whether the output is appended, the default is +false+.
549
+ # specifies whether the output is appended.
550
+ #
551
+ # The default is +false+.
463
552
  #
464
553
  # @example
465
554
  # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr'
466
555
  # @example
467
556
  # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr', true
557
+ #
468
558
  def stdout_redirect(stdout=nil, stderr=nil, append=false)
469
559
  @options[:redirect_stdout] = stdout
470
560
  @options[:redirect_stderr] = stderr
@@ -475,8 +565,9 @@ module Puma
475
565
  @options[:log_formatter] = block
476
566
  end
477
567
 
478
- # Configure +min+ to be the minimum number of threads to use to answer
479
- # requests and +max+ the maximum.
568
+ # Configure the number of threads to use to answer requests.
569
+ #
570
+ # It can be a single fixed number, or a +min+ and a +max+.
480
571
  #
481
572
  # The default is the environment variables +PUMA_MIN_THREADS+ / +PUMA_MAX_THREADS+
482
573
  # (or +MIN_THREADS+ / +MAX_THREADS+ if the +PUMA_+ variables aren't set).
@@ -484,10 +575,13 @@ module Puma
484
575
  # If these environment variables aren't set, the default is "0, 5" in MRI or "0, 16" for other interpreters.
485
576
  #
486
577
  # @example
578
+ # threads 5
579
+ # @example
487
580
  # threads 0, 16
488
581
  # @example
489
582
  # threads 5, 5
490
- def threads(min, max)
583
+ #
584
+ def threads(min, max = min)
491
585
  min = Integer(min)
492
586
  max = Integer(max)
493
587
  if min > max
@@ -502,6 +596,29 @@ module Puma
502
596
  @options[:max_threads] = max
503
597
  end
504
598
 
599
+ # Configure the max number of IO threads.
600
+ #
601
+ # When request handlers know the current requests will no longer use a significant amount
602
+ # of CPU, they can mark the current request as IO bound using <tt>env["puma.mark_as_io_bound"]</tt>.
603
+ #
604
+ # Threads marked as IO bound are allowed to go over the max thread limit.
605
+ #
606
+ # @example
607
+ # threads 5
608
+ # max_io_threads 5
609
+ #
610
+ # The above example allows for 5 regular threads and 5 IO threads to process requests concurrently.
611
+ # Any IO thread over the limit is counted as a regular thread, hence the above configuration also
612
+ # allows for 3 regular threads and 7 IO threads for example.
613
+ def max_io_threads(max)
614
+ max = Integer(max)
615
+ if max < 0
616
+ raise "The maximum number of IO threads (#{max}) must be a positive number"
617
+ end
618
+
619
+ @options[:max_io_threads] = max
620
+ end
621
+
505
622
  # Instead of using +bind+ and manually constructing a URI like:
506
623
  #
507
624
  # bind 'ssl://127.0.0.1:9292?key=key_path&cert=cert_path'
@@ -527,6 +644,7 @@ module Puma
527
644
  # cert: path_to_cert,
528
645
  # key: path_to_key,
529
646
  # ssl_cipher_filter: cipher_filter, # optional
647
+ # ssl_ciphersuites: ciphersuites, # optional
530
648
  # verify_mode: verify_mode, # default 'none'
531
649
  # verification_flags: flags, # optional, not supported by JRuby
532
650
  # reuse: true # optional
@@ -549,6 +667,7 @@ module Puma
549
667
  # ssl_cipher_list: cipher_list, # optional
550
668
  # verify_mode: verify_mode # default 'none'
551
669
  # }
670
+ #
552
671
  def ssl_bind(host, port, opts = {})
553
672
  add_pem_values_to_options_store(opts)
554
673
  bind self.class.ssl_bind_str(host, port, opts)
@@ -559,30 +678,42 @@ module Puma
559
678
  #
560
679
  # @example
561
680
  # state_path '/u/apps/lolcat/tmp/pids/puma.state'
681
+ #
562
682
  def state_path(path)
563
683
  @options[:state] = path.to_s
564
684
  end
565
685
 
566
- # Use +permission+ to restrict permissions for the state file.
686
+ # Use +permission+ to restrict permissions for the state file. By convention,
687
+ # +permission+ is an octal number (e.g. `0640` or `0o640`).
567
688
  #
568
689
  # @example
569
690
  # state_permission 0600
570
- # @version 5.0.0
571
691
  #
572
692
  def state_permission(permission)
573
693
  @options[:state_permission] = permission
574
694
  end
575
695
 
576
- # How many worker processes to run. Typically this is set to
577
- # the number of available cores.
696
+ # How many worker processes to run. Typically this is set to the number of
697
+ # available cores.
578
698
  #
579
699
  # The default is the value of the environment variable +WEB_CONCURRENCY+ if
580
- # set, otherwise 0.
700
+ # set, otherwise 0. Passing +:auto+ will set the value to
701
+ # +Concurrent.available_processor_count+ (requires the concurrent-ruby gem).
702
+ # On some platforms (e.g. under CPU quotas) this may be fractional, and Puma
703
+ # will round down. If it rounds down to 0, Puma will run in single mode and
704
+ # cluster-only hooks like +before_worker_boot+ will not execute.
705
+ # If you rely on cluster-only hooks, set an explicit worker count.
706
+ #
707
+ # A value of 0 or nil means run in single mode.
708
+ #
709
+ # @example
710
+ # workers 2
711
+ # workers :auto
581
712
  #
582
- # @note Cluster mode only.
583
713
  # @see Puma::Cluster
714
+ #
584
715
  def workers(count)
585
- @options[:workers] = count.to_i
716
+ @options[:workers] = count.nil? ? 0 : @config.send(:parse_workers, count)
586
717
  end
587
718
 
588
719
  # Disable warning message when running in cluster mode with a single worker.
@@ -598,16 +729,66 @@ module Puma
598
729
  #
599
730
  # Moving from workers = 1 to workers = 0 will save 10-30% of memory use.
600
731
  #
732
+ # The default is +false+.
733
+ #
601
734
  # @note Cluster mode only.
735
+ #
736
+ # @example
737
+ # silence_single_worker_warning
738
+ #
602
739
  def silence_single_worker_warning
603
740
  @options[:silence_single_worker_warning] = true
604
741
  end
605
742
 
606
743
  # Disable warning message when running single mode with callback hook defined.
744
+ #
745
+ # The default is +false+.
746
+ #
747
+ # @example
748
+ # silence_fork_callback_warning
749
+ #
607
750
  def silence_fork_callback_warning
608
751
  @options[:silence_fork_callback_warning] = true
609
752
  end
610
753
 
754
+ # Code to run only in single mode.
755
+ # Runs after all config files are loaded.
756
+ #
757
+ # This can be called multiple times.
758
+ #
759
+ # @note Single mode only.
760
+ #
761
+ # @example
762
+ # single do
763
+ # silence_fork_callback_warning
764
+ # end
765
+ #
766
+ def single(&block)
767
+ raise ArgumentError, "A block must be provided to `single`" unless block
768
+
769
+ @options[:single] ||= []
770
+ @options[:single] << block
771
+ end
772
+
773
+ # Code to run only in cluster mode.
774
+ # Runs after all config files are loaded.
775
+ #
776
+ # This can be called multiple times.
777
+ #
778
+ # @note Cluster mode only.
779
+ #
780
+ # @example
781
+ # cluster do
782
+ # prune_bundler
783
+ # end
784
+ #
785
+ def cluster(&block)
786
+ raise ArgumentError, "A block must be provided to `cluster`" unless block
787
+
788
+ @options[:cluster] ||= []
789
+ @options[:cluster] << block
790
+ end
791
+
611
792
  # Code to run immediately before master process
612
793
  # forks workers (once on boot). These hooks can block if necessary
613
794
  # to wait for background operations unknown to Puma to finish before
@@ -618,15 +799,14 @@ module Puma
618
799
  # This can be called multiple times to add several hooks.
619
800
  #
620
801
  # @note Cluster mode only.
802
+ #
621
803
  # @example
622
804
  # before_fork do
623
805
  # puts "Starting workers..."
624
806
  # end
807
+ #
625
808
  def before_fork(&block)
626
- warn_if_in_single_mode('before_fork')
627
-
628
- @options[:before_fork] ||= []
629
- @options[:before_fork] << block
809
+ process_hook :before_fork, nil, block, cluster_only: true
630
810
  end
631
811
 
632
812
  # Code to run in a worker when it boots to setup
@@ -635,77 +815,123 @@ module Puma
635
815
  # This can be called multiple times to add several hooks.
636
816
  #
637
817
  # @note Cluster mode only.
818
+ #
638
819
  # @example
639
- # on_worker_boot do
820
+ # before_worker_boot do
640
821
  # puts 'Before worker boot...'
641
822
  # end
642
- def on_worker_boot(key = nil, &block)
643
- warn_if_in_single_mode('on_worker_boot')
823
+ #
824
+ def before_worker_boot(key = nil, &block)
825
+ Puma.deprecate_method_change :on_worker_boot, __callee__, __method__
644
826
 
645
- process_hook :before_worker_boot, key, block, 'on_worker_boot'
827
+ process_hook :before_worker_boot, key, block, cluster_only: true
646
828
  end
647
829
 
830
+ alias_method :on_worker_boot, :before_worker_boot
831
+
648
832
  # Code to run immediately before a worker shuts
649
- # down (after it has finished processing HTTP requests). These hooks
833
+ # down (after it has finished processing HTTP requests). The worker's
834
+ # index is passed as an argument. These hooks
650
835
  # can block if necessary to wait for background operations unknown
651
836
  # to Puma to finish before the process terminates.
652
837
  #
653
838
  # This can be called multiple times to add several hooks.
654
839
  #
655
840
  # @note Cluster mode only.
841
+ #
656
842
  # @example
657
- # on_worker_shutdown do
843
+ # before_worker_shutdown do
658
844
  # puts 'On worker shutdown...'
659
845
  # end
660
- def on_worker_shutdown(key = nil, &block)
661
- warn_if_in_single_mode('on_worker_shutdown')
846
+ #
847
+ def before_worker_shutdown(key = nil, &block)
848
+ Puma.deprecate_method_change :on_worker_shutdown, __callee__, __method__
662
849
 
663
- process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
850
+ process_hook :before_worker_shutdown, key, block, cluster_only: true
664
851
  end
665
852
 
853
+ alias_method :on_worker_shutdown, :before_worker_shutdown
854
+
666
855
  # Code to run in the master right before a worker is started. The worker's
667
856
  # index is passed as an argument.
668
857
  #
669
858
  # This can be called multiple times to add several hooks.
670
859
  #
671
860
  # @note Cluster mode only.
861
+ #
672
862
  # @example
673
- # on_worker_fork do
863
+ # before_worker_fork do
674
864
  # puts 'Before worker fork...'
675
865
  # end
676
- def on_worker_fork(&block)
677
- warn_if_in_single_mode('on_worker_fork')
866
+ #
867
+ def before_worker_fork(&block)
868
+ Puma.deprecate_method_change :on_worker_fork, __callee__, __method__
678
869
 
679
- process_hook :before_worker_fork, nil, block, 'on_worker_fork'
870
+ process_hook :before_worker_fork, nil, block, cluster_only: true
680
871
  end
681
872
 
873
+ alias_method :on_worker_fork, :before_worker_fork
874
+
682
875
  # Code to run in the master after a worker has been started. The worker's
683
876
  # index is passed as an argument.
684
877
  #
685
878
  # This is called everytime a worker is to be started.
686
879
  #
687
880
  # @note Cluster mode only.
881
+ #
688
882
  # @example
689
883
  # after_worker_fork do
690
884
  # puts 'After worker fork...'
691
885
  # end
886
+ #
692
887
  def after_worker_fork(&block)
693
- warn_if_in_single_mode('after_worker_fork')
694
-
695
- process_hook :after_worker_fork, nil, block, 'after_worker_fork'
888
+ process_hook :after_worker_fork, nil, block, cluster_only: true
696
889
  end
697
890
 
698
891
  alias_method :after_worker_boot, :after_worker_fork
699
892
 
700
- # Code to run after puma is booted (works for both: single and clustered)
893
+ # Code to run in the master right after a worker has stopped. The worker's
894
+ # index and Process::Status are passed as arguments.
895
+ #
896
+ # @note Cluster mode only.
701
897
  #
702
898
  # @example
703
- # on_booted do
899
+ # after_worker_shutdown do |worker_handle|
900
+ # puts 'Worker crashed' unless worker_handle.process_status.success?
901
+ # end
902
+ #
903
+ def after_worker_shutdown(&block)
904
+ process_hook :after_worker_shutdown, nil, block, cluster_only: true
905
+ end
906
+
907
+ # Code to run after puma is booted (works for both single and cluster modes).
908
+ #
909
+ # @example
910
+ # after_booted do
704
911
  # puts 'After booting...'
705
912
  # end
706
- def on_booted(&block)
707
- @config.options[:events].on_booted(&block)
913
+ #
914
+ def after_booted(&block)
915
+ Puma.deprecate_method_change :on_booted, __callee__, __method__
916
+
917
+ @config.events.after_booted(&block)
918
+ end
919
+
920
+ alias_method :on_booted, :after_booted
921
+
922
+ # Code to run after puma is stopped (works for both: single and clustered)
923
+ #
924
+ # @example
925
+ # after_stopped do
926
+ # puts 'After stopping...'
927
+ # end
928
+ #
929
+ def after_stopped(&block)
930
+ Puma.deprecate_method_change :on_stopped, __callee__, __method__
931
+
932
+ @config.events.after_stopped(&block)
708
933
  end
934
+ alias_method :on_stopped, :after_stopped
709
935
 
710
936
  # When `fork_worker` is enabled, code to run in Worker 0
711
937
  # before all other workers are re-forked from this process,
@@ -719,14 +945,41 @@ module Puma
719
945
  # This can be called multiple times to add several hooks.
720
946
  #
721
947
  # @note Cluster mode with `fork_worker` enabled only.
948
+ #
722
949
  # @example
723
- # on_refork do
950
+ # before_refork do
724
951
  # 3.times {GC.start}
725
952
  # end
953
+ #
726
954
  # @version 5.0.0
727
955
  #
728
- def on_refork(key = nil, &block)
729
- process_hook :before_refork, key, block, 'on_refork'
956
+ def before_refork(key = nil, &block)
957
+ Puma.deprecate_method_change :on_refork, __callee__, __method__
958
+
959
+ process_hook :before_refork, key, block, cluster_only: true
960
+ end
961
+
962
+ alias_method :on_refork, :before_refork
963
+
964
+ # When `fork_worker` is enabled, code to run in Worker 0
965
+ # after all other workers are re-forked from this process,
966
+ # after the server has temporarily stopped serving requests
967
+ # (once per complete refork cycle).
968
+ #
969
+ # This can be used to re-open any connections to remote servers
970
+ # (database, Redis, ...) that were closed via before_refork.
971
+ #
972
+ # This can be called multiple times to add several hooks.
973
+ #
974
+ # @note Cluster mode with `fork_worker` enabled only.
975
+ #
976
+ # @example
977
+ # after_refork do
978
+ # puts 'After refork...'
979
+ # end
980
+ #
981
+ def after_refork(key = nil, &block)
982
+ process_hook :after_refork, key, block
730
983
  end
731
984
 
732
985
  # Provide a block to be executed just before a thread is added to the thread
@@ -742,14 +995,18 @@ module Puma
742
995
  # This can be called multiple times to add several hooks.
743
996
  #
744
997
  # @example
745
- # on_thread_start do
998
+ # before_thread_start do
746
999
  # puts 'On thread start...'
747
1000
  # end
748
- def on_thread_start(&block)
749
- @options[:before_thread_start] ||= []
750
- @options[:before_thread_start] << block
1001
+ #
1002
+ def before_thread_start(&block)
1003
+ Puma.deprecate_method_change :on_thread_start, __callee__, __method__
1004
+
1005
+ process_hook :before_thread_start, nil, block
751
1006
  end
752
1007
 
1008
+ alias_method :on_thread_start, :before_thread_start
1009
+
753
1010
  # Provide a block to be executed after a thread is trimmed from the thread
754
1011
  # pool. Be careful: while this block executes, Puma's main loop is
755
1012
  # blocked, so no new requests will be picked up.
@@ -766,14 +1023,18 @@ module Puma
766
1023
  # This can be called multiple times to add several hooks.
767
1024
  #
768
1025
  # @example
769
- # on_thread_exit do
1026
+ # before_thread_exit do
770
1027
  # puts 'On thread exit...'
771
1028
  # end
772
- def on_thread_exit(&block)
773
- @options[:before_thread_exit] ||= []
774
- @options[:before_thread_exit] << block
1029
+ #
1030
+ def before_thread_exit(&block)
1031
+ Puma.deprecate_method_change :on_thread_exit, __callee__, __method__
1032
+
1033
+ process_hook :before_thread_exit, nil, block
775
1034
  end
776
1035
 
1036
+ alias_method :on_thread_exit, :before_thread_exit
1037
+
777
1038
  # Code to run out-of-band when the worker is idle.
778
1039
  # These hooks run immediately after a request has finished
779
1040
  # processing and there are no busy threads on the worker.
@@ -783,8 +1044,9 @@ module Puma
783
1044
  # or scheduling asynchronous tasks to execute after a response.
784
1045
  #
785
1046
  # This can be called multiple times to add several hooks.
1047
+ #
786
1048
  def out_of_band(&block)
787
- process_hook :out_of_band, nil, block, 'out_of_band'
1049
+ process_hook :out_of_band, nil, block
788
1050
  end
789
1051
 
790
1052
  # The directory to operate out of.
@@ -793,16 +1055,22 @@ module Puma
793
1055
  #
794
1056
  # @example
795
1057
  # directory '/u/apps/lolcat'
1058
+ #
796
1059
  def directory(dir)
797
1060
  @options[:directory] = dir.to_s
798
1061
  end
799
1062
 
800
- # Preload the application before starting the workers; this conflicts with
801
- # phased restart feature. On by default if your app uses more than 1 worker.
1063
+ # Preload the application before forking the workers; this conflicts with
1064
+ # the phased restart feature.
1065
+ #
1066
+ # The default is +true+ if your app uses more than 1 worker.
802
1067
  #
803
1068
  # @note Cluster mode only.
1069
+ # @note When using `fork_worker`, this only applies to worker 0.
1070
+ #
804
1071
  # @example
805
1072
  # preload_app!
1073
+ #
806
1074
  def preload_app!(answer=true)
807
1075
  @options[:preload_app] = answer
808
1076
  end
@@ -814,6 +1082,7 @@ module Puma
814
1082
  # lowlevel_error_handler do |err|
815
1083
  # [200, {}, ["error page"]]
816
1084
  # end
1085
+ #
817
1086
  def lowlevel_error_handler(obj=nil, &block)
818
1087
  obj ||= block
819
1088
  raise "Provide either a #call'able or a block" unless obj
@@ -833,23 +1102,27 @@ module Puma
833
1102
  # new Bundler context and thus can float around as the release
834
1103
  # dictates.
835
1104
  #
836
- # @see extra_runtime_dependencies
837
- #
1105
+ # @note Cluster mode only.
838
1106
  # @note This is incompatible with +preload_app!+.
839
1107
  # @note This is only supported for RubyGems 2.2+
1108
+ #
1109
+ # @see extra_runtime_dependencies
1110
+ #
840
1111
  def prune_bundler(answer=true)
841
1112
  @options[:prune_bundler] = answer
842
1113
  end
843
1114
 
844
- # By default, Puma will raise SignalException when SIGTERM is received. In
845
- # environments where SIGTERM is something expected, you can suppress these
846
- # with this option.
1115
+ # Raises a SignalException when SIGTERM is received. In environments where
1116
+ # SIGTERM is something expected, you can suppress these with this option.
847
1117
  #
848
1118
  # This can be useful for example in Kubernetes, where rolling restart is
849
- # guaranteed usually on infrastructure level.
1119
+ # guaranteed usually on the infrastructure level.
1120
+ #
1121
+ # The default is +true+.
850
1122
  #
851
1123
  # @example
852
1124
  # raise_exception_on_sigterm false
1125
+ #
853
1126
  # @see Puma::Launcher#setup_signals
854
1127
  # @see Puma::Cluster#setup_signals
855
1128
  #
@@ -868,6 +1141,7 @@ module Puma
868
1141
  # extra_runtime_dependencies ['gem_name_1', 'gem_name_2']
869
1142
  # @example
870
1143
  # extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku']
1144
+ #
871
1145
  # @see Puma::Launcher#extra_runtime_deps_directories
872
1146
  #
873
1147
  def extra_runtime_dependencies(answer = [])
@@ -879,21 +1153,26 @@ module Puma
879
1153
  # If you do not specify a tag, Puma will infer it. If you do not want Puma
880
1154
  # to add a tag, use an empty string.
881
1155
  #
1156
+ # The default is the current file or directory base name.
1157
+ #
882
1158
  # @example
883
1159
  # tag 'app name'
884
1160
  # @example
885
1161
  # tag ''
1162
+ #
886
1163
  def tag(string)
887
1164
  @options[:tag] = string.to_s
888
1165
  end
889
1166
 
890
1167
  # Change the default interval for checking workers.
891
1168
  #
892
- # The default value is 5 seconds.
1169
+ # The default is 5 seconds.
893
1170
  #
894
1171
  # @note Cluster mode only.
1172
+ #
895
1173
  # @example
896
- # worker_check_interval 5
1174
+ # worker_check_interval 10
1175
+ #
897
1176
  # @see Puma::Cluster#check_workers
898
1177
  #
899
1178
  def worker_check_interval(interval)
@@ -906,11 +1185,14 @@ module Puma
906
1185
  # Setting this value will not protect against slow requests.
907
1186
  #
908
1187
  # This value must be greater than worker_check_interval.
909
- # The default value is 60 seconds.
1188
+ #
1189
+ # The default is 60 seconds.
910
1190
  #
911
1191
  # @note Cluster mode only.
1192
+ #
912
1193
  # @example
913
1194
  # worker_timeout 60
1195
+ #
914
1196
  # @see Puma::Cluster::Worker#ping_timeout
915
1197
  #
916
1198
  def worker_timeout(timeout)
@@ -926,12 +1208,13 @@ module Puma
926
1208
 
927
1209
  # Change the default worker timeout for booting.
928
1210
  #
929
- # If unspecified, this defaults to the value of worker_timeout.
1211
+ # The default is 60 seconds.
930
1212
  #
931
1213
  # @note Cluster mode only.
932
1214
  #
933
1215
  # @example
934
1216
  # worker_boot_timeout 60
1217
+ #
935
1218
  # @see Puma::Cluster::Worker#ping_timeout
936
1219
  #
937
1220
  def worker_boot_timeout(timeout)
@@ -940,7 +1223,13 @@ module Puma
940
1223
 
941
1224
  # Set the timeout for worker shutdown.
942
1225
  #
1226
+ # The default is 30 seconds.
1227
+ #
943
1228
  # @note Cluster mode only.
1229
+ #
1230
+ # @example
1231
+ # worker_shutdown_timeout 90
1232
+ #
944
1233
  # @see Puma::Cluster::Worker#term
945
1234
  #
946
1235
  def worker_shutdown_timeout(timeout)
@@ -956,22 +1245,26 @@ module Puma
956
1245
  # 2. **:oldest** - the oldest workers (i.e. the workers that were started
957
1246
  # the longest time ago) will be culled.
958
1247
  #
1248
+ # The default is +:youngest+.
1249
+ #
959
1250
  # @note Cluster mode only.
1251
+ #
960
1252
  # @example
961
1253
  # worker_culling_strategy :oldest
1254
+ #
962
1255
  # @see Puma::Cluster#cull_workers
963
1256
  #
964
1257
  def worker_culling_strategy(strategy)
965
- stategy = strategy.to_sym
1258
+ strategy = strategy.to_sym
966
1259
 
967
1260
  if ![:youngest, :oldest].include?(strategy)
968
- raise "Invalid value for worker_culling_strategy - #{stategy}"
1261
+ raise "Invalid value for worker_culling_strategy - #{strategy}"
969
1262
  end
970
1263
 
971
1264
  @options[:worker_culling_strategy] = strategy
972
1265
  end
973
1266
 
974
- # When set to true (the default), workers accept all requests
1267
+ # When set to true, workers accept all requests
975
1268
  # and queue them before passing them to the handlers.
976
1269
  # When set to false, each worker process accepts exactly as
977
1270
  # many requests as it is configured to simultaneously handle.
@@ -984,7 +1277,11 @@ module Puma
984
1277
  # slow clients will occupy a handler thread while the request
985
1278
  # is being sent. A reverse proxy, such as nginx, can handle
986
1279
  # slow clients and queue requests before they reach Puma.
1280
+ #
1281
+ # The default is +true+.
1282
+ #
987
1283
  # @see Puma::Server
1284
+ #
988
1285
  def queue_requests(answer=true)
989
1286
  @options[:queue_requests] = answer
990
1287
  end
@@ -993,19 +1290,30 @@ module Puma
993
1290
  # threads will be written to $stdout. This can help figure
994
1291
  # out why shutdown is hanging.
995
1292
  #
996
- def shutdown_debug(val=true)
997
- @options[:shutdown_debug] = val
1293
+ # If `on_force` is true, the backtraces will be written only
1294
+ # when the shutdown is forced i.e. not graceful.
1295
+ #
1296
+ # @see force_shutdown_after
1297
+ def shutdown_debug(val = true, on_force: false)
1298
+ @options[:shutdown_debug] = val && on_force ? :on_force : val
998
1299
  end
999
1300
 
1000
-
1001
- # Attempts to route traffic to less-busy workers by causing them to delay
1002
- # listening on the socket, allowing workers which are not processing any
1301
+ # Maximum delay of worker accept loop.
1302
+ #
1303
+ # Attempts to route traffic to less-busy workers by causing a busy worker to delay
1304
+ # listening on the socket, allowing workers which are not processing as many
1003
1305
  # requests to pick up new requests first.
1004
1306
  #
1005
- # Only works on MRI. For all other interpreters, this setting does nothing.
1307
+ # The default is 0.005 seconds.
1308
+ #
1309
+ # To turn off this feature, set the value to 0.
1310
+ #
1311
+ # @note Cluster mode with >= 2 workers only.
1312
+ #
1313
+ # @note Interpreters with forking support only.
1314
+ #
1006
1315
  # @see Puma::Server#handle_servers
1007
1316
  # @see Puma::ThreadPool#wait_for_less_busy_worker
1008
- # @version 5.0.0
1009
1317
  #
1010
1318
  def wait_for_less_busy_worker(val=0.005)
1011
1319
  @options[:wait_for_less_busy_worker] = val.to_f
@@ -1018,7 +1326,7 @@ module Puma
1018
1326
  #
1019
1327
  # There are 5 possible values:
1020
1328
  #
1021
- # 1. **:socket** (the default) - read the peername from the socket using the
1329
+ # 1. **:socket** - read the peername from the socket using the
1022
1330
  # syscall. This is the normal behavior. If this fails for any reason (e.g.,
1023
1331
  # if the peer disconnects between the connection being accepted and the getpeername
1024
1332
  # system call), Puma will return "0.0.0.0"
@@ -1036,6 +1344,11 @@ module Puma
1036
1344
  # you wish. Because Puma never uses this field anyway, it's format is
1037
1345
  # entirely in your hands.
1038
1346
  #
1347
+ # The default is +:socket+.
1348
+ #
1349
+ # @example
1350
+ # set_remote_address :localhost
1351
+ #
1039
1352
  def set_remote_address(val=:socket)
1040
1353
  case val
1041
1354
  when :socket
@@ -1075,18 +1388,57 @@ module Puma
1075
1388
  # A refork will automatically trigger once after the specified number of requests
1076
1389
  # (default 1000), or pass 0 to disable auto refork.
1077
1390
  #
1391
+ # @note This is experimental.
1078
1392
  # @note Cluster mode only.
1079
- # @version 5.0.0
1080
1393
  #
1081
1394
  def fork_worker(after_requests=1000)
1082
1395
  @options[:fork_worker] = Integer(after_requests)
1083
1396
  end
1084
1397
 
1085
- # The number of requests to attempt inline before sending a client back to
1086
- # the reactor to be subject to normal ordering.
1398
+ # @deprecated Use {#max_keep_alive} instead.
1087
1399
  #
1088
1400
  def max_fast_inline(num_of_requests)
1089
- @options[:max_fast_inline] = Float(num_of_requests)
1401
+ Puma.deprecate_method_change :max_fast_inline, __method__, :max_keep_alive
1402
+ @options[:max_keep_alive] ||= Float(num_of_requests) unless num_of_requests.nil?
1403
+ end
1404
+
1405
+ # The number of requests a keep-alive client can submit before being closed.
1406
+ # Note that some applications (server to server) may benefit from a very high
1407
+ # number or Float::INFINITY.
1408
+ #
1409
+ # The default is 999.
1410
+ #
1411
+ # @example
1412
+ # max_keep_alive 20
1413
+ #
1414
+ def max_keep_alive(num_of_requests)
1415
+ @options[:max_keep_alive] = Float(num_of_requests) unless num_of_requests.nil?
1416
+ end
1417
+
1418
+ # When `true`, keep-alive connections are maintained on inbound requests.
1419
+ # Enabling this setting reduces the number of TCP operations, reducing response
1420
+ # times for connections that can send multiple requests in a single connection.
1421
+ #
1422
+ # When Puma receives more incoming connections than available Puma threads,
1423
+ # enabling the keep-alive behavior may result in processing requests out-of-order,
1424
+ # increasing overall response time variance. Increased response time variance
1425
+ # means that the overall average of response times might not change, but more
1426
+ # outliers will exist. Those long-tail outliers may significantly affect response
1427
+ # times for some processed requests.
1428
+ #
1429
+ # When `false`, Puma closes the connection after each request, requiring the
1430
+ # client to open a new request. Disabling this setting guarantees that requests
1431
+ # will be processed in the order they are fully received, decreasing response
1432
+ # variance and eliminating long-tail outliers caused by keep-alive behavior.
1433
+ # The trade-off is that the number of TCP operations required will increase.
1434
+ #
1435
+ # The default is +true+.
1436
+ #
1437
+ # @example
1438
+ # enable_keep_alives false
1439
+ #
1440
+ def enable_keep_alives(enabled=true)
1441
+ @options[:enable_keep_alives] = enabled
1090
1442
  end
1091
1443
 
1092
1444
  # Specify the backend for the IO selector.
@@ -1102,12 +1454,20 @@ module Puma
1102
1454
  #
1103
1455
  # The default is +:auto+.
1104
1456
  #
1105
- # @see https://github.com/socketry/nio4r/blob/master/lib/nio/selector.rb
1457
+ # @see https://github.com/socketry/nio4r/blob/main/lib/nio/selector.rb
1106
1458
  #
1107
1459
  def io_selector_backend(backend)
1108
1460
  @options[:io_selector_backend] = backend.to_sym
1109
1461
  end
1110
1462
 
1463
+ # Ensures +STDOUT+ and +STDERR+ is immediately flushed to the underlying
1464
+ # operating system and is not buffered internally
1465
+ #
1466
+ # The default is +true+.
1467
+ #
1468
+ # @example
1469
+ # mutate_stdout_and_stderr_to_sync_on_write false
1470
+ #
1111
1471
  def mutate_stdout_and_stderr_to_sync_on_write(enabled=true)
1112
1472
  @options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled
1113
1473
  end
@@ -1119,8 +1479,12 @@ module Puma
1119
1479
  #
1120
1480
  # When no Content-Length http header is present, it is compared against the
1121
1481
  # size of the body of the request.
1122
- #
1123
- # The default value for http_content_length_limit is nil.
1482
+ #
1483
+ # The default is +nil+.
1484
+ #
1485
+ # @example
1486
+ # http_content_length_limit 2_000_000_000
1487
+ #
1124
1488
  def http_content_length_limit(limit)
1125
1489
  @options[:http_content_length_limit] = limit
1126
1490
  end
@@ -1161,6 +1525,7 @@ module Puma
1161
1525
 
1162
1526
  # To avoid adding cert_pem and key_pem as URI params, we store them on the
1163
1527
  # options[:store] from where Puma binder knows how to find and extract them.
1528
+ #
1164
1529
  def add_pem_values_to_options_store(opts)
1165
1530
  return if defined?(JRUBY_VERSION)
1166
1531
 
@@ -1177,30 +1542,21 @@ module Puma
1177
1542
  end
1178
1543
  end
1179
1544
 
1180
- def process_hook(options_key, key, block, meth)
1545
+ def process_hook(options_key, key, block, cluster_only: false)
1546
+ raise ArgumentError, "expected #{options_key} to be given a block" unless block
1547
+
1548
+ @config.hooks[options_key] = true
1549
+
1181
1550
  @options[options_key] ||= []
1182
- if ON_WORKER_KEY.include? key.class
1183
- @options[options_key] << [block, key.to_sym]
1551
+ hook_options = { block: block, cluster_only: cluster_only }
1552
+ hook_options[:id] = if ON_WORKER_KEY.include?(key.class)
1553
+ key.to_sym
1184
1554
  elsif key.nil?
1185
- @options[options_key] << block
1555
+ nil
1186
1556
  else
1187
- raise "'#{meth}' key must be String or Symbol"
1188
- end
1189
- end
1190
-
1191
- def warn_if_in_single_mode(hook_name)
1192
- return if @options[:silence_fork_callback_warning]
1193
- # user_options (CLI) have precedence over config file
1194
- workers_val = @config.options.user_options[:workers] || @options[:workers] ||
1195
- @config.puma_default_options[:workers] || 0
1196
- if workers_val == 0
1197
- log_string =
1198
- "Warning: You specified code to run in a `#{hook_name}` block, " \
1199
- "but Puma is not configured to run in cluster mode (worker count > 0 ), " \
1200
- "so your `#{hook_name}` block did not run"
1201
-
1202
- LogWriter.stdio.log(log_string)
1557
+ raise "'#{options_key}' key must be String or Symbol"
1203
1558
  end
1559
+ @options[options_key] << hook_options
1204
1560
  end
1205
1561
  end
1206
1562
  end