puma 6.4.0 → 6.6.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +235 -18
  3. data/README.md +87 -26
  4. data/docs/fork_worker.md +11 -1
  5. data/docs/java_options.md +54 -0
  6. data/docs/kubernetes.md +1 -1
  7. data/docs/plugins.md +4 -0
  8. data/docs/restart.md +1 -0
  9. data/docs/signals.md +2 -2
  10. data/docs/stats.md +8 -3
  11. data/docs/systemd.md +13 -6
  12. data/ext/puma_http11/extconf.rb +21 -14
  13. data/ext/puma_http11/mini_ssl.c +16 -2
  14. data/ext/puma_http11/org/jruby/puma/Http11.java +31 -8
  15. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +2 -1
  16. data/ext/puma_http11/puma_http11.c +4 -1
  17. data/lib/puma/app/status.rb +1 -1
  18. data/lib/puma/binder.rb +12 -4
  19. data/lib/puma/cli.rb +9 -5
  20. data/lib/puma/client.rb +104 -16
  21. data/lib/puma/cluster/worker.rb +9 -6
  22. data/lib/puma/cluster/worker_handle.rb +4 -5
  23. data/lib/puma/cluster.rb +112 -27
  24. data/lib/puma/configuration.rb +37 -21
  25. data/lib/puma/const.rb +22 -3
  26. data/lib/puma/control_cli.rb +4 -4
  27. data/lib/puma/detect.rb +3 -4
  28. data/lib/puma/dsl.rb +303 -58
  29. data/lib/puma/error_logger.rb +4 -4
  30. data/lib/puma/jruby_restart.rb +0 -16
  31. data/lib/puma/launcher.rb +21 -8
  32. data/lib/puma/log_writer.rb +9 -9
  33. data/lib/puma/minissl/context_builder.rb +3 -0
  34. data/lib/puma/minissl.rb +6 -0
  35. data/lib/puma/null_io.rb +42 -2
  36. data/lib/puma/request.rb +35 -14
  37. data/lib/puma/runner.rb +10 -3
  38. data/lib/puma/sd_notify.rb +1 -4
  39. data/lib/puma/server.rb +53 -21
  40. data/lib/puma/single.rb +1 -1
  41. data/lib/puma/state_file.rb +2 -2
  42. data/lib/puma/thread_pool.rb +14 -2
  43. data/lib/puma/util.rb +1 -1
  44. data/lib/rack/handler/puma.rb +8 -5
  45. data/tools/Dockerfile +5 -3
  46. metadata +10 -12
data/lib/puma/dsl.rb CHANGED
@@ -47,11 +47,13 @@ module Puma
47
47
  # | on_worker_boot | :before_worker_boot | inside, before |
48
48
  # | on_worker_shutdown | :before_worker_shutdown | inside, after |
49
49
  # | on_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
@@ -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,7 @@ 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
+ #
213
220
  def activate_control_app(url="auto", opts={})
214
221
  if url == "auto"
215
222
  path = Configuration.temp_path
@@ -235,8 +242,12 @@ module Puma
235
242
  @options[:control_url_umask] = opts[:umask] if opts[:umask]
236
243
  end
237
244
 
238
- # Load additional configuration from a file
239
- # Files get loaded later via Configuration#load
245
+ # Load additional configuration from a file.
246
+ # Files get loaded later via Configuration#load.
247
+ #
248
+ # @example
249
+ # load 'config/puma/production.rb'
250
+ #
240
251
  def load(file)
241
252
  @options[:config_files] ||= []
242
253
  @options[:config_files] << file
@@ -268,6 +279,7 @@ module Puma
268
279
  # bind 'tcp://0.0.0.0:9292?low_latency=false'
269
280
  # @example Socket permissions
270
281
  # bind 'unix:///var/run/puma.sock?umask=0111'
282
+ #
271
283
  # @see Puma::Runner#load_and_bind
272
284
  # @see Puma::Cluster#run
273
285
  #
@@ -302,39 +314,70 @@ module Puma
302
314
  #
303
315
  # @example Only bind to systemd activated sockets, ignoring other binds
304
316
  # bind_to_activated_sockets 'only'
317
+ #
305
318
  def bind_to_activated_sockets(bind=true)
306
319
  @options[:bind_to_activated_sockets] = bind
307
320
  end
308
321
 
309
- # Define the TCP port to bind to. Use +bind+ for more advanced options.
322
+ # Define the TCP port to bind to. Use `bind` for more advanced options.
323
+ #
324
+ # The default is +9292+.
310
325
  #
311
326
  # @example
312
- # port 9292
327
+ # port 3000
328
+ #
313
329
  def port(port, host=nil)
314
330
  host ||= default_host
315
331
  bind URI::Generic.build(scheme: 'tcp', host: host, port: Integer(port)).to_s
316
332
  end
317
333
 
318
334
  # Define how long the tcp socket stays open, if no data has been received.
335
+ #
336
+ # The default is 30 seconds.
337
+ #
338
+ # @example
339
+ # first_data_timeout 40
340
+ #
319
341
  # @see Puma::Server.new
342
+ #
320
343
  def first_data_timeout(seconds)
321
344
  @options[:first_data_timeout] = Integer(seconds)
322
345
  end
323
346
 
324
347
  # Define how long persistent connections can be idle before Puma closes them.
348
+ #
349
+ # The default is 20 seconds.
350
+ #
351
+ # @example
352
+ # persistent_timeout 30
353
+ #
325
354
  # @see Puma::Server.new
355
+ #
326
356
  def persistent_timeout(seconds)
327
357
  @options[:persistent_timeout] = Integer(seconds)
328
358
  end
329
359
 
330
360
  # If a new request is not received within this number of seconds, begin shutting down.
361
+ #
362
+ # The default is +nil+.
363
+ #
364
+ # @example
365
+ # idle_timeout 60
366
+ #
331
367
  # @see Puma::Server.new
368
+ #
332
369
  def idle_timeout(seconds)
333
370
  @options[:idle_timeout] = Integer(seconds)
334
371
  end
335
372
 
336
373
  # Work around leaky apps that leave garbage in Thread locals
337
374
  # across requests.
375
+ #
376
+ # The default is +false+.
377
+ #
378
+ # @example
379
+ # clean_thread_locals
380
+ #
338
381
  def clean_thread_locals(which=true)
339
382
  @options[:clean_thread_locals] = which
340
383
  end
@@ -342,6 +385,7 @@ module Puma
342
385
  # When shutting down, drain the accept socket of pending connections and
343
386
  # process them. This loops over the accept socket until there are no more
344
387
  # read events and then stops looking and waits for the requests to finish.
388
+ #
345
389
  # @see Puma::Server#graceful_shutdown
346
390
  #
347
391
  def drain_on_shutdown(which=true)
@@ -355,18 +399,22 @@ module Puma
355
399
  #
356
400
  # @example
357
401
  # environment 'production'
402
+ #
358
403
  def environment(environment)
359
404
  @options[:environment] = environment
360
405
  end
361
406
 
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.
407
+ # How long to wait for threads to stop when shutting them down.
408
+ # Specifying :immediately will cause Puma to kill the threads immediately.
409
+ # Otherwise the value is the number of seconds to wait.
366
410
  #
367
411
  # Puma always waits a few seconds after killing a thread for it to try
368
412
  # to finish up it's work, even in :immediately mode.
413
+ #
414
+ # The default is +:forever+.
415
+ #
369
416
  # @see Puma::Server#graceful_shutdown
417
+ #
370
418
  def force_shutdown_after(val=:forever)
371
419
  i = case val
372
420
  when :forever
@@ -389,9 +437,9 @@ module Puma
389
437
  # on_restart do
390
438
  # puts 'On restart...'
391
439
  # end
440
+ #
392
441
  def on_restart(&block)
393
- @options[:on_restart] ||= []
394
- @options[:on_restart] << block
442
+ process_hook :on_restart, nil, block, 'on_restart'
395
443
  end
396
444
 
397
445
  # Command to use to restart Puma. This should be just how to
@@ -400,6 +448,7 @@ module Puma
400
448
  #
401
449
  # @example
402
450
  # restart_command '/u/app/lolcat/bin/restart_puma'
451
+ #
403
452
  def restart_command(cmd)
404
453
  @options[:restart_cmd] = cmd.to_s
405
454
  end
@@ -408,31 +457,49 @@ module Puma
408
457
  #
409
458
  # @example
410
459
  # pidfile '/u/apps/lolcat/tmp/pids/puma.pid'
460
+ #
411
461
  def pidfile(path)
412
462
  @options[:pidfile] = path.to_s
413
463
  end
414
464
 
415
- # Disable request logging, if this isn't used it'll be enabled by default.
465
+ # Disable request logging, the inverse of `log_requests`.
466
+ #
467
+ # The default is +true+.
416
468
  #
417
469
  # @example
418
470
  # quiet
471
+ #
419
472
  def quiet(which=true)
420
473
  @options[:log_requests] = !which
421
474
  end
422
475
 
423
- # Enable request logging
476
+ # Enable request logging, the inverse of `quiet`.
477
+ #
478
+ # The default is +false+.
479
+ #
480
+ # @example
481
+ # log_requests
424
482
  #
425
483
  def log_requests(which=true)
426
484
  @options[:log_requests] = which
427
485
  end
428
486
 
429
487
  # Pass in a custom logging class instance
488
+ #
489
+ # @example
490
+ # custom_logger Logger.new('t.log')
491
+ #
430
492
  def custom_logger(custom_logger)
431
493
  @options[:custom_logger] = custom_logger
432
494
  end
433
495
 
434
496
  # Show debugging info
435
497
  #
498
+ # The default is +false+.
499
+ #
500
+ # @example
501
+ # debug
502
+ #
436
503
  def debug
437
504
  @options[:debug] = true
438
505
  end
@@ -443,6 +510,7 @@ module Puma
443
510
  #
444
511
  # @example
445
512
  # rackup '/u/apps/lolcat/config.ru'
513
+ #
446
514
  def rackup(path)
447
515
  @options[:rackup] ||= path.to_s
448
516
  end
@@ -450,21 +518,32 @@ module Puma
450
518
  # Allows setting `env['rack.url_scheme']`.
451
519
  # Only necessary if X-Forwarded-Proto is not being set by your proxy
452
520
  # Normal values are 'http' or 'https'.
521
+ #
453
522
  def rack_url_scheme(scheme=nil)
454
523
  @options[:rack_url_scheme] = scheme
455
524
  end
456
525
 
526
+ # Enable HTTP 103 Early Hints responses.
527
+ #
528
+ # The default is +nil+.
529
+ #
530
+ # @example
531
+ # early_hints
532
+ #
457
533
  def early_hints(answer=true)
458
534
  @options[:early_hints] = answer
459
535
  end
460
536
 
461
537
  # Redirect +STDOUT+ and +STDERR+ to files specified. The +append+ parameter
462
- # specifies whether the output is appended, the default is +false+.
538
+ # specifies whether the output is appended.
539
+ #
540
+ # The default is +false+.
463
541
  #
464
542
  # @example
465
543
  # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr'
466
544
  # @example
467
545
  # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr', true
546
+ #
468
547
  def stdout_redirect(stdout=nil, stderr=nil, append=false)
469
548
  @options[:redirect_stdout] = stdout
470
549
  @options[:redirect_stderr] = stderr
@@ -475,8 +554,9 @@ module Puma
475
554
  @options[:log_formatter] = block
476
555
  end
477
556
 
478
- # Configure +min+ to be the minimum number of threads to use to answer
479
- # requests and +max+ the maximum.
557
+ # Configure the number of threads to use to answer requests.
558
+ #
559
+ # It can be a single fixed number, or a +min+ and a +max+.
480
560
  #
481
561
  # The default is the environment variables +PUMA_MIN_THREADS+ / +PUMA_MAX_THREADS+
482
562
  # (or +MIN_THREADS+ / +MAX_THREADS+ if the +PUMA_+ variables aren't set).
@@ -484,10 +564,13 @@ module Puma
484
564
  # If these environment variables aren't set, the default is "0, 5" in MRI or "0, 16" for other interpreters.
485
565
  #
486
566
  # @example
567
+ # threads 5
568
+ # @example
487
569
  # threads 0, 16
488
570
  # @example
489
571
  # threads 5, 5
490
- def threads(min, max)
572
+ #
573
+ def threads(min, max = min)
491
574
  min = Integer(min)
492
575
  max = Integer(max)
493
576
  if min > max
@@ -527,6 +610,7 @@ module Puma
527
610
  # cert: path_to_cert,
528
611
  # key: path_to_key,
529
612
  # ssl_cipher_filter: cipher_filter, # optional
613
+ # ssl_ciphersuites: ciphersuites, # optional
530
614
  # verify_mode: verify_mode, # default 'none'
531
615
  # verification_flags: flags, # optional, not supported by JRuby
532
616
  # reuse: true # optional
@@ -549,6 +633,7 @@ module Puma
549
633
  # ssl_cipher_list: cipher_list, # optional
550
634
  # verify_mode: verify_mode # default 'none'
551
635
  # }
636
+ #
552
637
  def ssl_bind(host, port, opts = {})
553
638
  add_pem_values_to_options_store(opts)
554
639
  bind self.class.ssl_bind_str(host, port, opts)
@@ -559,6 +644,7 @@ module Puma
559
644
  #
560
645
  # @example
561
646
  # state_path '/u/apps/lolcat/tmp/pids/puma.state'
647
+ #
562
648
  def state_path(path)
563
649
  @options[:state] = path.to_s
564
650
  end
@@ -567,7 +653,6 @@ module Puma
567
653
  #
568
654
  # @example
569
655
  # state_permission 0600
570
- # @version 5.0.0
571
656
  #
572
657
  def state_permission(permission)
573
658
  @options[:state_permission] = permission
@@ -580,7 +665,12 @@ module Puma
580
665
  # set, otherwise 0.
581
666
  #
582
667
  # @note Cluster mode only.
668
+ #
669
+ # @example
670
+ # workers 2
671
+ #
583
672
  # @see Puma::Cluster
673
+ #
584
674
  def workers(count)
585
675
  @options[:workers] = count.to_i
586
676
  end
@@ -598,12 +688,24 @@ module Puma
598
688
  #
599
689
  # Moving from workers = 1 to workers = 0 will save 10-30% of memory use.
600
690
  #
691
+ # The default is +false+.
692
+ #
601
693
  # @note Cluster mode only.
694
+ #
695
+ # @example
696
+ # silence_single_worker_warning
697
+ #
602
698
  def silence_single_worker_warning
603
699
  @options[:silence_single_worker_warning] = true
604
700
  end
605
701
 
606
702
  # Disable warning message when running single mode with callback hook defined.
703
+ #
704
+ # The default is +false+.
705
+ #
706
+ # @example
707
+ # silence_fork_callback_warning
708
+ #
607
709
  def silence_fork_callback_warning
608
710
  @options[:silence_fork_callback_warning] = true
609
711
  end
@@ -618,15 +720,16 @@ module Puma
618
720
  # This can be called multiple times to add several hooks.
619
721
  #
620
722
  # @note Cluster mode only.
723
+ #
621
724
  # @example
622
725
  # before_fork do
623
726
  # puts "Starting workers..."
624
727
  # end
728
+ #
625
729
  def before_fork(&block)
626
730
  warn_if_in_single_mode('before_fork')
627
731
 
628
- @options[:before_fork] ||= []
629
- @options[:before_fork] << block
732
+ process_hook :before_fork, nil, block, 'before_fork'
630
733
  end
631
734
 
632
735
  # Code to run in a worker when it boots to setup
@@ -635,10 +738,12 @@ module Puma
635
738
  # This can be called multiple times to add several hooks.
636
739
  #
637
740
  # @note Cluster mode only.
741
+ #
638
742
  # @example
639
743
  # on_worker_boot do
640
744
  # puts 'Before worker boot...'
641
745
  # end
746
+ #
642
747
  def on_worker_boot(key = nil, &block)
643
748
  warn_if_in_single_mode('on_worker_boot')
644
749
 
@@ -646,17 +751,20 @@ module Puma
646
751
  end
647
752
 
648
753
  # Code to run immediately before a worker shuts
649
- # down (after it has finished processing HTTP requests). These hooks
754
+ # down (after it has finished processing HTTP requests). The worker's
755
+ # index is passed as an argument. These hooks
650
756
  # can block if necessary to wait for background operations unknown
651
757
  # to Puma to finish before the process terminates.
652
758
  #
653
759
  # This can be called multiple times to add several hooks.
654
760
  #
655
761
  # @note Cluster mode only.
762
+ #
656
763
  # @example
657
764
  # on_worker_shutdown do
658
765
  # puts 'On worker shutdown...'
659
766
  # end
767
+ #
660
768
  def on_worker_shutdown(key = nil, &block)
661
769
  warn_if_in_single_mode('on_worker_shutdown')
662
770
 
@@ -669,10 +777,12 @@ module Puma
669
777
  # This can be called multiple times to add several hooks.
670
778
  #
671
779
  # @note Cluster mode only.
780
+ #
672
781
  # @example
673
782
  # on_worker_fork do
674
783
  # puts 'Before worker fork...'
675
784
  # end
785
+ #
676
786
  def on_worker_fork(&block)
677
787
  warn_if_in_single_mode('on_worker_fork')
678
788
 
@@ -685,10 +795,12 @@ module Puma
685
795
  # This is called everytime a worker is to be started.
686
796
  #
687
797
  # @note Cluster mode only.
798
+ #
688
799
  # @example
689
800
  # after_worker_fork do
690
801
  # puts 'After worker fork...'
691
802
  # end
803
+ #
692
804
  def after_worker_fork(&block)
693
805
  warn_if_in_single_mode('after_worker_fork')
694
806
 
@@ -697,16 +809,28 @@ module Puma
697
809
 
698
810
  alias_method :after_worker_boot, :after_worker_fork
699
811
 
700
- # Code to run after puma is booted (works for both: single and clustered)
812
+ # Code to run after puma is booted (works for both single and cluster modes).
701
813
  #
702
814
  # @example
703
815
  # on_booted do
704
816
  # puts 'After booting...'
705
817
  # end
818
+ #
706
819
  def on_booted(&block)
707
820
  @config.options[:events].on_booted(&block)
708
821
  end
709
822
 
823
+ # Code to run after puma is stopped (works for both single and cluster modes).
824
+ #
825
+ # @example
826
+ # on_stopped do
827
+ # puts 'After stopping...'
828
+ # end
829
+ #
830
+ def on_stopped(&block)
831
+ @config.options[:events].on_stopped(&block)
832
+ end
833
+
710
834
  # When `fork_worker` is enabled, code to run in Worker 0
711
835
  # before all other workers are re-forked from this process,
712
836
  # after the server has temporarily stopped serving requests
@@ -719,21 +843,48 @@ module Puma
719
843
  # This can be called multiple times to add several hooks.
720
844
  #
721
845
  # @note Cluster mode with `fork_worker` enabled only.
846
+ #
722
847
  # @example
723
848
  # on_refork do
724
849
  # 3.times {GC.start}
725
850
  # end
726
- # @version 5.0.0
727
851
  #
728
852
  def on_refork(key = nil, &block)
853
+ warn_if_in_single_mode('on_refork')
854
+
729
855
  process_hook :before_refork, key, block, 'on_refork'
730
856
  end
731
857
 
732
- # Code to run immediately before a thread starts. The worker does not
733
- # start new threads until this code finishes.
858
+ # When `fork_worker` is enabled, code to run in Worker 0
859
+ # after all other workers are re-forked from this process,
860
+ # after the server has temporarily stopped serving requests
861
+ # (once per complete refork cycle).
734
862
  #
735
- # This hook is useful for doing something when a thread
736
- # starts.
863
+ # This can be used to re-open any connections to remote servers
864
+ # (database, Redis, ...) that were closed via on_refork.
865
+ #
866
+ # This can be called multiple times to add several hooks.
867
+ #
868
+ # @note Cluster mode with `fork_worker` enabled only.
869
+ #
870
+ # @example
871
+ # after_refork do
872
+ # puts 'After refork...'
873
+ # end
874
+ #
875
+ def after_refork(key = nil, &block)
876
+ process_hook :after_refork, key, block, 'after_refork'
877
+ end
878
+
879
+ # Provide a block to be executed just before a thread is added to the thread
880
+ # pool. Be careful: while the block executes, thread creation is delayed, and
881
+ # probably a request will have to wait too! The new thread will not be added to
882
+ # the threadpool until the provided block returns.
883
+ #
884
+ # Return values are ignored.
885
+ # Raising an exception will log a warning.
886
+ #
887
+ # This hook is useful for doing something when the thread pool grows.
737
888
  #
738
889
  # This can be called multiple times to add several hooks.
739
890
  #
@@ -741,13 +892,20 @@ module Puma
741
892
  # on_thread_start do
742
893
  # puts 'On thread start...'
743
894
  # end
895
+ #
744
896
  def on_thread_start(&block)
745
- @options[:before_thread_start] ||= []
746
- @options[:before_thread_start] << block
897
+ process_hook :before_thread_start, nil, block, 'on_thread_start'
747
898
  end
748
899
 
749
- # Code to run immediately before a thread exits. The worker does not
750
- # accept new requests until this code finishes.
900
+ # Provide a block to be executed after a thread is trimmed from the thread
901
+ # pool. Be careful: while this block executes, Puma's main loop is
902
+ # blocked, so no new requests will be picked up.
903
+ #
904
+ # This hook only runs when a thread in the threadpool is trimmed by Puma.
905
+ # It does not run when a thread dies due to exceptions or any other cause.
906
+ #
907
+ # Return values are ignored.
908
+ # Raising an exception will log a warning.
751
909
  #
752
910
  # This hook is useful for cleaning up thread local resources when a thread
753
911
  # is trimmed.
@@ -758,9 +916,9 @@ module Puma
758
916
  # on_thread_exit do
759
917
  # puts 'On thread exit...'
760
918
  # end
919
+ #
761
920
  def on_thread_exit(&block)
762
- @options[:before_thread_exit] ||= []
763
- @options[:before_thread_exit] << block
921
+ process_hook :before_thread_exit, nil, block, 'on_thread_exit'
764
922
  end
765
923
 
766
924
  # Code to run out-of-band when the worker is idle.
@@ -772,6 +930,7 @@ module Puma
772
930
  # or scheduling asynchronous tasks to execute after a response.
773
931
  #
774
932
  # This can be called multiple times to add several hooks.
933
+ #
775
934
  def out_of_band(&block)
776
935
  process_hook :out_of_band, nil, block, 'out_of_band'
777
936
  end
@@ -782,16 +941,21 @@ module Puma
782
941
  #
783
942
  # @example
784
943
  # directory '/u/apps/lolcat'
944
+ #
785
945
  def directory(dir)
786
946
  @options[:directory] = dir.to_s
787
947
  end
788
948
 
789
949
  # Preload the application before starting the workers; this conflicts with
790
- # phased restart feature. On by default if your app uses more than 1 worker.
950
+ # phased restart feature.
951
+ #
952
+ # The default is +true+ if your app uses more than 1 worker.
791
953
  #
792
954
  # @note Cluster mode only.
955
+ #
793
956
  # @example
794
957
  # preload_app!
958
+ #
795
959
  def preload_app!(answer=true)
796
960
  @options[:preload_app] = answer
797
961
  end
@@ -803,6 +967,7 @@ module Puma
803
967
  # lowlevel_error_handler do |err|
804
968
  # [200, {}, ["error page"]]
805
969
  # end
970
+ #
806
971
  def lowlevel_error_handler(obj=nil, &block)
807
972
  obj ||= block
808
973
  raise "Provide either a #call'able or a block" unless obj
@@ -822,23 +987,26 @@ module Puma
822
987
  # new Bundler context and thus can float around as the release
823
988
  # dictates.
824
989
  #
825
- # @see extra_runtime_dependencies
826
- #
827
990
  # @note This is incompatible with +preload_app!+.
828
991
  # @note This is only supported for RubyGems 2.2+
992
+ #
993
+ # @see extra_runtime_dependencies
994
+ #
829
995
  def prune_bundler(answer=true)
830
996
  @options[:prune_bundler] = answer
831
997
  end
832
998
 
833
- # By default, Puma will raise SignalException when SIGTERM is received. In
834
- # environments where SIGTERM is something expected, you can suppress these
835
- # with this option.
999
+ # Raises a SignalException when SIGTERM is received. In environments where
1000
+ # SIGTERM is something expected, you can suppress these with this option.
836
1001
  #
837
1002
  # This can be useful for example in Kubernetes, where rolling restart is
838
- # guaranteed usually on infrastructure level.
1003
+ # guaranteed usually on the infrastructure level.
1004
+ #
1005
+ # The default is +true+.
839
1006
  #
840
1007
  # @example
841
1008
  # raise_exception_on_sigterm false
1009
+ #
842
1010
  # @see Puma::Launcher#setup_signals
843
1011
  # @see Puma::Cluster#setup_signals
844
1012
  #
@@ -857,6 +1025,7 @@ module Puma
857
1025
  # extra_runtime_dependencies ['gem_name_1', 'gem_name_2']
858
1026
  # @example
859
1027
  # extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku']
1028
+ #
860
1029
  # @see Puma::Launcher#extra_runtime_deps_directories
861
1030
  #
862
1031
  def extra_runtime_dependencies(answer = [])
@@ -868,21 +1037,26 @@ module Puma
868
1037
  # If you do not specify a tag, Puma will infer it. If you do not want Puma
869
1038
  # to add a tag, use an empty string.
870
1039
  #
1040
+ # The default is the current file or directory base name.
1041
+ #
871
1042
  # @example
872
1043
  # tag 'app name'
873
1044
  # @example
874
1045
  # tag ''
1046
+ #
875
1047
  def tag(string)
876
1048
  @options[:tag] = string.to_s
877
1049
  end
878
1050
 
879
1051
  # Change the default interval for checking workers.
880
1052
  #
881
- # The default value is 5 seconds.
1053
+ # The default is 5 seconds.
882
1054
  #
883
1055
  # @note Cluster mode only.
1056
+ #
884
1057
  # @example
885
- # worker_check_interval 5
1058
+ # worker_check_interval 10
1059
+ #
886
1060
  # @see Puma::Cluster#check_workers
887
1061
  #
888
1062
  def worker_check_interval(interval)
@@ -895,11 +1069,14 @@ module Puma
895
1069
  # Setting this value will not protect against slow requests.
896
1070
  #
897
1071
  # This value must be greater than worker_check_interval.
898
- # The default value is 60 seconds.
1072
+ #
1073
+ # The default is 60 seconds.
899
1074
  #
900
1075
  # @note Cluster mode only.
1076
+ #
901
1077
  # @example
902
1078
  # worker_timeout 60
1079
+ #
903
1080
  # @see Puma::Cluster::Worker#ping_timeout
904
1081
  #
905
1082
  def worker_timeout(timeout)
@@ -915,12 +1092,13 @@ module Puma
915
1092
 
916
1093
  # Change the default worker timeout for booting.
917
1094
  #
918
- # If unspecified, this defaults to the value of worker_timeout.
1095
+ # The default is the value of `worker_timeout`.
919
1096
  #
920
1097
  # @note Cluster mode only.
921
1098
  #
922
1099
  # @example
923
1100
  # worker_boot_timeout 60
1101
+ #
924
1102
  # @see Puma::Cluster::Worker#ping_timeout
925
1103
  #
926
1104
  def worker_boot_timeout(timeout)
@@ -929,7 +1107,13 @@ module Puma
929
1107
 
930
1108
  # Set the timeout for worker shutdown.
931
1109
  #
1110
+ # The default is 30 seconds.
1111
+ #
932
1112
  # @note Cluster mode only.
1113
+ #
1114
+ # @example
1115
+ # worker_shutdown_timeout 90
1116
+ #
933
1117
  # @see Puma::Cluster::Worker#term
934
1118
  #
935
1119
  def worker_shutdown_timeout(timeout)
@@ -945,22 +1129,26 @@ module Puma
945
1129
  # 2. **:oldest** - the oldest workers (i.e. the workers that were started
946
1130
  # the longest time ago) will be culled.
947
1131
  #
1132
+ # The default is +:youngest+.
1133
+ #
948
1134
  # @note Cluster mode only.
1135
+ #
949
1136
  # @example
950
1137
  # worker_culling_strategy :oldest
1138
+ #
951
1139
  # @see Puma::Cluster#cull_workers
952
1140
  #
953
1141
  def worker_culling_strategy(strategy)
954
- stategy = strategy.to_sym
1142
+ strategy = strategy.to_sym
955
1143
 
956
1144
  if ![:youngest, :oldest].include?(strategy)
957
- raise "Invalid value for worker_culling_strategy - #{stategy}"
1145
+ raise "Invalid value for worker_culling_strategy - #{strategy}"
958
1146
  end
959
1147
 
960
1148
  @options[:worker_culling_strategy] = strategy
961
1149
  end
962
1150
 
963
- # When set to true (the default), workers accept all requests
1151
+ # When set to true, workers accept all requests
964
1152
  # and queue them before passing them to the handlers.
965
1153
  # When set to false, each worker process accepts exactly as
966
1154
  # many requests as it is configured to simultaneously handle.
@@ -973,7 +1161,11 @@ module Puma
973
1161
  # slow clients will occupy a handler thread while the request
974
1162
  # is being sent. A reverse proxy, such as nginx, can handle
975
1163
  # slow clients and queue requests before they reach Puma.
1164
+ #
1165
+ # The default is +true+.
1166
+ #
976
1167
  # @see Puma::Server
1168
+ #
977
1169
  def queue_requests(answer=true)
978
1170
  @options[:queue_requests] = answer
979
1171
  end
@@ -991,10 +1183,12 @@ module Puma
991
1183
  # listening on the socket, allowing workers which are not processing any
992
1184
  # requests to pick up new requests first.
993
1185
  #
1186
+ # The default is 0.005 seconds.
1187
+ #
994
1188
  # Only works on MRI. For all other interpreters, this setting does nothing.
1189
+ #
995
1190
  # @see Puma::Server#handle_servers
996
1191
  # @see Puma::ThreadPool#wait_for_less_busy_worker
997
- # @version 5.0.0
998
1192
  #
999
1193
  def wait_for_less_busy_worker(val=0.005)
1000
1194
  @options[:wait_for_less_busy_worker] = val.to_f
@@ -1007,7 +1201,7 @@ module Puma
1007
1201
  #
1008
1202
  # There are 5 possible values:
1009
1203
  #
1010
- # 1. **:socket** (the default) - read the peername from the socket using the
1204
+ # 1. **:socket** - read the peername from the socket using the
1011
1205
  # syscall. This is the normal behavior. If this fails for any reason (e.g.,
1012
1206
  # if the peer disconnects between the connection being accepted and the getpeername
1013
1207
  # system call), Puma will return "0.0.0.0"
@@ -1025,6 +1219,11 @@ module Puma
1025
1219
  # you wish. Because Puma never uses this field anyway, it's format is
1026
1220
  # entirely in your hands.
1027
1221
  #
1222
+ # The default is +:socket+.
1223
+ #
1224
+ # @example
1225
+ # set_remote_address :localhost
1226
+ #
1028
1227
  def set_remote_address(val=:socket)
1029
1228
  case val
1030
1229
  when :socket
@@ -1064,8 +1263,8 @@ module Puma
1064
1263
  # A refork will automatically trigger once after the specified number of requests
1065
1264
  # (default 1000), or pass 0 to disable auto refork.
1066
1265
  #
1266
+ # @note This is experimental.
1067
1267
  # @note Cluster mode only.
1068
- # @version 5.0.0
1069
1268
  #
1070
1269
  def fork_worker(after_requests=1000)
1071
1270
  @options[:fork_worker] = Integer(after_requests)
@@ -1074,10 +1273,41 @@ module Puma
1074
1273
  # The number of requests to attempt inline before sending a client back to
1075
1274
  # the reactor to be subject to normal ordering.
1076
1275
  #
1276
+ # The default is 10.
1277
+ #
1278
+ # @example
1279
+ # max_fast_inline 20
1280
+ #
1077
1281
  def max_fast_inline(num_of_requests)
1078
1282
  @options[:max_fast_inline] = Float(num_of_requests)
1079
1283
  end
1080
1284
 
1285
+ # When `true`, keep-alive connections are maintained on inbound requests.
1286
+ # Enabling this setting reduces the number of TCP operations, reducing response
1287
+ # times for connections that can send multiple requests in a single connection.
1288
+ #
1289
+ # When Puma receives more incoming connections than available Puma threads,
1290
+ # enabling the keep-alive behavior may result in processing requests out-of-order,
1291
+ # increasing overall response time variance. Increased response time variance
1292
+ # means that the overall average of response times might not change, but more
1293
+ # outliers will exist. Those long-tail outliers may significantly affect response
1294
+ # times for some processed requests.
1295
+ #
1296
+ # When `false`, Puma closes the connection after each request, requiring the
1297
+ # client to open a new request. Disabling this setting guarantees that requests
1298
+ # will be processed in the order they are fully received, decreasing response
1299
+ # variance and eliminating long-tail outliers caused by keep-alive behavior.
1300
+ # The trade-off is that the number of TCP operations required will increase.
1301
+ #
1302
+ # The default is +true+.
1303
+ #
1304
+ # @example
1305
+ # enable_keep_alives false
1306
+ #
1307
+ def enable_keep_alives(enabled=true)
1308
+ @options[:enable_keep_alives] = enabled
1309
+ end
1310
+
1081
1311
  # Specify the backend for the IO selector.
1082
1312
  #
1083
1313
  # Provided values will be passed directly to +NIO::Selector.new+, with the
@@ -1097,6 +1327,14 @@ module Puma
1097
1327
  @options[:io_selector_backend] = backend.to_sym
1098
1328
  end
1099
1329
 
1330
+ # Ensures +STDOUT+ and +STDERR+ is immediately flushed to the underlying
1331
+ # operating system and is not buffered internally
1332
+ #
1333
+ # The default is +true+.
1334
+ #
1335
+ # @example
1336
+ # mutate_stdout_and_stderr_to_sync_on_write false
1337
+ #
1100
1338
  def mutate_stdout_and_stderr_to_sync_on_write(enabled=true)
1101
1339
  @options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled
1102
1340
  end
@@ -1108,8 +1346,12 @@ module Puma
1108
1346
  #
1109
1347
  # When no Content-Length http header is present, it is compared against the
1110
1348
  # size of the body of the request.
1111
- #
1112
- # The default value for http_content_length_limit is nil.
1349
+ #
1350
+ # The default is +nil+.
1351
+ #
1352
+ # @example
1353
+ # http_content_length_limit 2_000_000_000
1354
+ #
1113
1355
  def http_content_length_limit(limit)
1114
1356
  @options[:http_content_length_limit] = limit
1115
1357
  end
@@ -1150,6 +1392,7 @@ module Puma
1150
1392
 
1151
1393
  # To avoid adding cert_pem and key_pem as URI params, we store them on the
1152
1394
  # options[:store] from where Puma binder knows how to find and extract them.
1395
+ #
1153
1396
  def add_pem_values_to_options_store(opts)
1154
1397
  return if defined?(JRUBY_VERSION)
1155
1398
 
@@ -1179,12 +1422,14 @@ module Puma
1179
1422
 
1180
1423
  def warn_if_in_single_mode(hook_name)
1181
1424
  return if @options[:silence_fork_callback_warning]
1182
-
1183
- if (@options[:workers] || 0) == 0
1425
+ # user_options (CLI) have precedence over config file
1426
+ workers_val = @config.options.user_options[:workers] || @options[:workers] ||
1427
+ @config.puma_default_options[:workers] || 0
1428
+ if workers_val == 0
1184
1429
  log_string =
1185
1430
  "Warning: You specified code to run in a `#{hook_name}` block, " \
1186
- "but Puma is not configured to run in cluster mode (worker count > 0 ), " \
1187
- "so your `#{hook_name}` block did not run"
1431
+ "but Puma is not configured to run in cluster mode (worker count > 0), " \
1432
+ "so your `#{hook_name}` block will not run."
1188
1433
 
1189
1434
  LogWriter.stdio.log(log_string)
1190
1435
  end