puma 6.6.0 → 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.
- checksums.yaml +4 -4
- data/History.md +309 -5
- data/README.md +41 -42
- data/docs/5.0-Upgrade.md +98 -0
- data/docs/6.0-Upgrade.md +56 -0
- data/docs/7.0-Upgrade.md +52 -0
- data/docs/8.0-Upgrade.md +100 -0
- data/docs/deployment.md +58 -23
- data/docs/fork_worker.md +5 -5
- data/docs/grpc.md +62 -0
- data/docs/images/favicon.svg +1 -0
- data/docs/images/running-puma.svg +1 -0
- data/docs/images/standard-logo.svg +1 -0
- data/docs/jungle/README.md +1 -1
- data/docs/kubernetes.md +11 -16
- data/docs/plugins.md +2 -2
- data/docs/restart.md +2 -2
- data/docs/signals.md +21 -21
- data/docs/stats.md +4 -3
- data/docs/systemd.md +4 -4
- data/ext/puma_http11/extconf.rb +2 -17
- data/ext/puma_http11/http11_parser.java.rl +51 -65
- data/ext/puma_http11/mini_ssl.c +18 -8
- data/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +174 -102
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +71 -85
- data/ext/puma_http11/puma_http11.c +122 -118
- data/lib/puma/app/status.rb +10 -2
- data/lib/puma/binder.rb +12 -10
- data/lib/puma/cli.rb +4 -6
- data/lib/puma/client.rb +205 -131
- data/lib/puma/client_env.rb +171 -0
- data/lib/puma/cluster/worker.rb +17 -17
- data/lib/puma/cluster/worker_handle.rb +38 -7
- data/lib/puma/cluster.rb +44 -30
- data/lib/puma/cluster_accept_loop_delay.rb +91 -0
- data/lib/puma/commonlogger.rb +3 -3
- data/lib/puma/configuration.rb +173 -58
- data/lib/puma/const.rb +11 -11
- data/lib/puma/control_cli.rb +7 -3
- data/lib/puma/detect.rb +13 -0
- data/lib/puma/dsl.rb +225 -108
- data/lib/puma/error_logger.rb +3 -1
- data/lib/puma/events.rb +25 -10
- data/lib/puma/io_buffer.rb +8 -4
- data/lib/puma/launcher/bundle_pruner.rb +3 -5
- data/lib/puma/launcher.rb +57 -53
- data/lib/puma/log_writer.rb +8 -2
- data/lib/puma/minissl.rb +0 -1
- data/lib/puma/plugin/systemd.rb +3 -3
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/reactor.rb +19 -13
- data/lib/puma/{request.rb → response.rb} +56 -212
- data/lib/puma/runner.rb +9 -18
- data/lib/puma/server.rb +182 -97
- data/lib/puma/server_plugin_control.rb +32 -0
- data/lib/puma/single.rb +7 -4
- data/lib/puma/state_file.rb +3 -2
- data/lib/puma/thread_pool.rb +170 -99
- data/lib/puma/util.rb +0 -7
- data/lib/puma.rb +10 -0
- data/lib/rack/handler/puma.rb +3 -3
- data/tools/Dockerfile +15 -5
- metadata +19 -7
- 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.
|
|
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.
|
|
28
|
+
# config.clamp
|
|
29
29
|
#
|
|
30
30
|
# puts config.options[:binds] # => "tcp://127.0.0.1:3002"
|
|
31
31
|
#
|
|
@@ -43,11 +43,11 @@ module Puma
|
|
|
43
43
|
#
|
|
44
44
|
# The following hooks have been updated:
|
|
45
45
|
#
|
|
46
|
-
# | DSL Method
|
|
47
|
-
# |
|
|
48
|
-
# |
|
|
49
|
-
# |
|
|
50
|
-
# | after_refork
|
|
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 |
|
|
51
51
|
#
|
|
52
52
|
class DSL
|
|
53
53
|
ON_WORKER_KEY = [String, Symbol].freeze
|
|
@@ -155,7 +155,7 @@ module Puma
|
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
def default_host
|
|
158
|
-
@options[:default_host] || Configuration
|
|
158
|
+
@options[:default_host] || Configuration.default_tcp_host
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def inject(&blk)
|
|
@@ -216,6 +216,8 @@ module Puma
|
|
|
216
216
|
# activate_control_app 'unix:///var/run/pumactl.sock', { auth_token: '12345' }
|
|
217
217
|
# @example
|
|
218
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}
|
|
219
221
|
#
|
|
220
222
|
def activate_control_app(url="auto", opts={})
|
|
221
223
|
if url == "auto"
|
|
@@ -240,6 +242,7 @@ module Puma
|
|
|
240
242
|
|
|
241
243
|
@options[:control_auth_token] = auth_token
|
|
242
244
|
@options[:control_url_umask] = opts[:umask] if opts[:umask]
|
|
245
|
+
@options[:control_data_only] = opts[:data_only] if opts[:data_only]
|
|
243
246
|
end
|
|
244
247
|
|
|
245
248
|
# Load additional configuration from a file.
|
|
@@ -257,7 +260,8 @@ module Puma
|
|
|
257
260
|
# accepted protocols. Multiple urls can be bound to, calling +bind+ does
|
|
258
261
|
# not overwrite previous bindings.
|
|
259
262
|
#
|
|
260
|
-
# The default is "tcp://
|
|
263
|
+
# The default is "tcp://[::]:9292" when IPv6 interfaces are available,
|
|
264
|
+
# otherwise "tcp://0.0.0.0:9292".
|
|
261
265
|
#
|
|
262
266
|
# You can use query parameters within the url to specify options:
|
|
263
267
|
#
|
|
@@ -276,7 +280,7 @@ module Puma
|
|
|
276
280
|
# @example SSL cert for mutual TLS (mTLS)
|
|
277
281
|
# bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem&ca=ca.pem&verify_mode=force_peer'
|
|
278
282
|
# @example Disable optimization for low latency
|
|
279
|
-
# bind 'tcp://
|
|
283
|
+
# bind 'tcp://[::]:9292?low_latency=false'
|
|
280
284
|
# @example Socket permissions
|
|
281
285
|
# bind 'unix:///var/run/puma.sock?umask=0111'
|
|
282
286
|
#
|
|
@@ -346,7 +350,7 @@ module Puma
|
|
|
346
350
|
|
|
347
351
|
# Define how long persistent connections can be idle before Puma closes them.
|
|
348
352
|
#
|
|
349
|
-
# The default is
|
|
353
|
+
# The default is 65 seconds.
|
|
350
354
|
#
|
|
351
355
|
# @example
|
|
352
356
|
# persistent_timeout 30
|
|
@@ -370,18 +374,21 @@ module Puma
|
|
|
370
374
|
@options[:idle_timeout] = Integer(seconds)
|
|
371
375
|
end
|
|
372
376
|
|
|
373
|
-
#
|
|
374
|
-
#
|
|
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.
|
|
375
380
|
#
|
|
376
381
|
# The default is +false+.
|
|
377
382
|
#
|
|
378
383
|
# @example
|
|
379
|
-
#
|
|
384
|
+
# fiber_per_request
|
|
380
385
|
#
|
|
381
|
-
def
|
|
382
|
-
@options[:
|
|
386
|
+
def fiber_per_request(which=true)
|
|
387
|
+
@options[:fiber_per_request] = which
|
|
383
388
|
end
|
|
384
389
|
|
|
390
|
+
alias clean_thread_locals fiber_per_request
|
|
391
|
+
|
|
385
392
|
# When shutting down, drain the accept socket of pending connections and
|
|
386
393
|
# process them. This loops over the accept socket until there are no more
|
|
387
394
|
# read events and then stops looking and waits for the requests to finish.
|
|
@@ -434,14 +441,18 @@ module Puma
|
|
|
434
441
|
# This can be called multiple times to add code each time.
|
|
435
442
|
#
|
|
436
443
|
# @example
|
|
437
|
-
#
|
|
444
|
+
# before_restart do
|
|
438
445
|
# puts 'On restart...'
|
|
439
446
|
# end
|
|
440
447
|
#
|
|
441
|
-
def
|
|
442
|
-
|
|
448
|
+
def before_restart(&block)
|
|
449
|
+
Puma.deprecate_method_change :on_restart, __callee__, __method__
|
|
450
|
+
|
|
451
|
+
process_hook :before_restart, nil, block
|
|
443
452
|
end
|
|
444
453
|
|
|
454
|
+
alias_method :on_restart, :before_restart
|
|
455
|
+
|
|
445
456
|
# Command to use to restart Puma. This should be just how to
|
|
446
457
|
# load Puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
|
|
447
458
|
# to Puma, as those are the same as the original process.
|
|
@@ -585,6 +596,29 @@ module Puma
|
|
|
585
596
|
@options[:max_threads] = max
|
|
586
597
|
end
|
|
587
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
|
+
|
|
588
622
|
# Instead of using +bind+ and manually constructing a URI like:
|
|
589
623
|
#
|
|
590
624
|
# bind 'ssl://127.0.0.1:9292?key=key_path&cert=cert_path'
|
|
@@ -649,32 +683,37 @@ module Puma
|
|
|
649
683
|
@options[:state] = path.to_s
|
|
650
684
|
end
|
|
651
685
|
|
|
652
|
-
# 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`).
|
|
653
688
|
#
|
|
654
689
|
# @example
|
|
655
690
|
# state_permission 0600
|
|
656
691
|
#
|
|
657
|
-
# @version 5.0.0
|
|
658
|
-
#
|
|
659
692
|
def state_permission(permission)
|
|
660
693
|
@options[:state_permission] = permission
|
|
661
694
|
end
|
|
662
695
|
|
|
663
|
-
# How many worker processes to run.
|
|
664
|
-
#
|
|
696
|
+
# How many worker processes to run. Typically this is set to the number of
|
|
697
|
+
# available cores.
|
|
665
698
|
#
|
|
666
699
|
# The default is the value of the environment variable +WEB_CONCURRENCY+ if
|
|
667
|
-
# 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.
|
|
668
706
|
#
|
|
669
|
-
#
|
|
707
|
+
# A value of 0 or nil means run in single mode.
|
|
670
708
|
#
|
|
671
709
|
# @example
|
|
672
710
|
# workers 2
|
|
711
|
+
# workers :auto
|
|
673
712
|
#
|
|
674
713
|
# @see Puma::Cluster
|
|
675
714
|
#
|
|
676
715
|
def workers(count)
|
|
677
|
-
@options[:workers] = count.
|
|
716
|
+
@options[:workers] = count.nil? ? 0 : @config.send(:parse_workers, count)
|
|
678
717
|
end
|
|
679
718
|
|
|
680
719
|
# Disable warning message when running in cluster mode with a single worker.
|
|
@@ -712,6 +751,44 @@ module Puma
|
|
|
712
751
|
@options[:silence_fork_callback_warning] = true
|
|
713
752
|
end
|
|
714
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
|
+
|
|
715
792
|
# Code to run immediately before master process
|
|
716
793
|
# forks workers (once on boot). These hooks can block if necessary
|
|
717
794
|
# to wait for background operations unknown to Puma to finish before
|
|
@@ -729,9 +806,7 @@ module Puma
|
|
|
729
806
|
# end
|
|
730
807
|
#
|
|
731
808
|
def before_fork(&block)
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
process_hook :before_fork, nil, block, 'before_fork'
|
|
809
|
+
process_hook :before_fork, nil, block, cluster_only: true
|
|
735
810
|
end
|
|
736
811
|
|
|
737
812
|
# Code to run in a worker when it boots to setup
|
|
@@ -742,16 +817,18 @@ module Puma
|
|
|
742
817
|
# @note Cluster mode only.
|
|
743
818
|
#
|
|
744
819
|
# @example
|
|
745
|
-
#
|
|
820
|
+
# before_worker_boot do
|
|
746
821
|
# puts 'Before worker boot...'
|
|
747
822
|
# end
|
|
748
823
|
#
|
|
749
|
-
def
|
|
750
|
-
|
|
824
|
+
def before_worker_boot(key = nil, &block)
|
|
825
|
+
Puma.deprecate_method_change :on_worker_boot, __callee__, __method__
|
|
751
826
|
|
|
752
|
-
process_hook :before_worker_boot, key, block,
|
|
827
|
+
process_hook :before_worker_boot, key, block, cluster_only: true
|
|
753
828
|
end
|
|
754
829
|
|
|
830
|
+
alias_method :on_worker_boot, :before_worker_boot
|
|
831
|
+
|
|
755
832
|
# Code to run immediately before a worker shuts
|
|
756
833
|
# down (after it has finished processing HTTP requests). The worker's
|
|
757
834
|
# index is passed as an argument. These hooks
|
|
@@ -763,16 +840,18 @@ module Puma
|
|
|
763
840
|
# @note Cluster mode only.
|
|
764
841
|
#
|
|
765
842
|
# @example
|
|
766
|
-
#
|
|
843
|
+
# before_worker_shutdown do
|
|
767
844
|
# puts 'On worker shutdown...'
|
|
768
845
|
# end
|
|
769
846
|
#
|
|
770
|
-
def
|
|
771
|
-
|
|
847
|
+
def before_worker_shutdown(key = nil, &block)
|
|
848
|
+
Puma.deprecate_method_change :on_worker_shutdown, __callee__, __method__
|
|
772
849
|
|
|
773
|
-
process_hook :before_worker_shutdown, key, block,
|
|
850
|
+
process_hook :before_worker_shutdown, key, block, cluster_only: true
|
|
774
851
|
end
|
|
775
852
|
|
|
853
|
+
alias_method :on_worker_shutdown, :before_worker_shutdown
|
|
854
|
+
|
|
776
855
|
# Code to run in the master right before a worker is started. The worker's
|
|
777
856
|
# index is passed as an argument.
|
|
778
857
|
#
|
|
@@ -781,16 +860,18 @@ module Puma
|
|
|
781
860
|
# @note Cluster mode only.
|
|
782
861
|
#
|
|
783
862
|
# @example
|
|
784
|
-
#
|
|
863
|
+
# before_worker_fork do
|
|
785
864
|
# puts 'Before worker fork...'
|
|
786
865
|
# end
|
|
787
866
|
#
|
|
788
|
-
def
|
|
789
|
-
|
|
867
|
+
def before_worker_fork(&block)
|
|
868
|
+
Puma.deprecate_method_change :on_worker_fork, __callee__, __method__
|
|
790
869
|
|
|
791
|
-
process_hook :before_worker_fork, nil, block,
|
|
870
|
+
process_hook :before_worker_fork, nil, block, cluster_only: true
|
|
792
871
|
end
|
|
793
872
|
|
|
873
|
+
alias_method :on_worker_fork, :before_worker_fork
|
|
874
|
+
|
|
794
875
|
# Code to run in the master after a worker has been started. The worker's
|
|
795
876
|
# index is passed as an argument.
|
|
796
877
|
#
|
|
@@ -804,34 +885,53 @@ module Puma
|
|
|
804
885
|
# end
|
|
805
886
|
#
|
|
806
887
|
def after_worker_fork(&block)
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
process_hook :after_worker_fork, nil, block, 'after_worker_fork'
|
|
888
|
+
process_hook :after_worker_fork, nil, block, cluster_only: true
|
|
810
889
|
end
|
|
811
890
|
|
|
812
891
|
alias_method :after_worker_boot, :after_worker_fork
|
|
813
892
|
|
|
814
|
-
# Code to run
|
|
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.
|
|
815
897
|
#
|
|
816
898
|
# @example
|
|
817
|
-
#
|
|
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
|
|
818
911
|
# puts 'After booting...'
|
|
819
912
|
# end
|
|
820
913
|
#
|
|
821
|
-
def
|
|
822
|
-
|
|
914
|
+
def after_booted(&block)
|
|
915
|
+
Puma.deprecate_method_change :on_booted, __callee__, __method__
|
|
916
|
+
|
|
917
|
+
@config.events.after_booted(&block)
|
|
823
918
|
end
|
|
824
919
|
|
|
920
|
+
alias_method :on_booted, :after_booted
|
|
921
|
+
|
|
825
922
|
# Code to run after puma is stopped (works for both: single and clustered)
|
|
826
923
|
#
|
|
827
924
|
# @example
|
|
828
|
-
#
|
|
925
|
+
# after_stopped do
|
|
829
926
|
# puts 'After stopping...'
|
|
830
927
|
# end
|
|
831
928
|
#
|
|
832
|
-
def
|
|
833
|
-
|
|
929
|
+
def after_stopped(&block)
|
|
930
|
+
Puma.deprecate_method_change :on_stopped, __callee__, __method__
|
|
931
|
+
|
|
932
|
+
@config.events.after_stopped(&block)
|
|
834
933
|
end
|
|
934
|
+
alias_method :on_stopped, :after_stopped
|
|
835
935
|
|
|
836
936
|
# When `fork_worker` is enabled, code to run in Worker 0
|
|
837
937
|
# before all other workers are re-forked from this process,
|
|
@@ -847,25 +947,27 @@ module Puma
|
|
|
847
947
|
# @note Cluster mode with `fork_worker` enabled only.
|
|
848
948
|
#
|
|
849
949
|
# @example
|
|
850
|
-
#
|
|
950
|
+
# before_refork do
|
|
851
951
|
# 3.times {GC.start}
|
|
852
952
|
# end
|
|
853
953
|
#
|
|
854
954
|
# @version 5.0.0
|
|
855
955
|
#
|
|
856
|
-
def
|
|
857
|
-
|
|
956
|
+
def before_refork(key = nil, &block)
|
|
957
|
+
Puma.deprecate_method_change :on_refork, __callee__, __method__
|
|
858
958
|
|
|
859
|
-
process_hook :before_refork, key, block,
|
|
959
|
+
process_hook :before_refork, key, block, cluster_only: true
|
|
860
960
|
end
|
|
861
961
|
|
|
962
|
+
alias_method :on_refork, :before_refork
|
|
963
|
+
|
|
862
964
|
# When `fork_worker` is enabled, code to run in Worker 0
|
|
863
965
|
# after all other workers are re-forked from this process,
|
|
864
966
|
# after the server has temporarily stopped serving requests
|
|
865
967
|
# (once per complete refork cycle).
|
|
866
968
|
#
|
|
867
969
|
# This can be used to re-open any connections to remote servers
|
|
868
|
-
# (database, Redis, ...) that were closed via
|
|
970
|
+
# (database, Redis, ...) that were closed via before_refork.
|
|
869
971
|
#
|
|
870
972
|
# This can be called multiple times to add several hooks.
|
|
871
973
|
#
|
|
@@ -877,7 +979,7 @@ module Puma
|
|
|
877
979
|
# end
|
|
878
980
|
#
|
|
879
981
|
def after_refork(key = nil, &block)
|
|
880
|
-
process_hook :after_refork, key, block
|
|
982
|
+
process_hook :after_refork, key, block
|
|
881
983
|
end
|
|
882
984
|
|
|
883
985
|
# Provide a block to be executed just before a thread is added to the thread
|
|
@@ -893,14 +995,18 @@ module Puma
|
|
|
893
995
|
# This can be called multiple times to add several hooks.
|
|
894
996
|
#
|
|
895
997
|
# @example
|
|
896
|
-
#
|
|
998
|
+
# before_thread_start do
|
|
897
999
|
# puts 'On thread start...'
|
|
898
1000
|
# end
|
|
899
1001
|
#
|
|
900
|
-
def
|
|
901
|
-
|
|
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
|
|
902
1006
|
end
|
|
903
1007
|
|
|
1008
|
+
alias_method :on_thread_start, :before_thread_start
|
|
1009
|
+
|
|
904
1010
|
# Provide a block to be executed after a thread is trimmed from the thread
|
|
905
1011
|
# pool. Be careful: while this block executes, Puma's main loop is
|
|
906
1012
|
# blocked, so no new requests will be picked up.
|
|
@@ -917,14 +1023,18 @@ module Puma
|
|
|
917
1023
|
# This can be called multiple times to add several hooks.
|
|
918
1024
|
#
|
|
919
1025
|
# @example
|
|
920
|
-
#
|
|
1026
|
+
# before_thread_exit do
|
|
921
1027
|
# puts 'On thread exit...'
|
|
922
1028
|
# end
|
|
923
1029
|
#
|
|
924
|
-
def
|
|
925
|
-
|
|
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
|
|
926
1034
|
end
|
|
927
1035
|
|
|
1036
|
+
alias_method :on_thread_exit, :before_thread_exit
|
|
1037
|
+
|
|
928
1038
|
# Code to run out-of-band when the worker is idle.
|
|
929
1039
|
# These hooks run immediately after a request has finished
|
|
930
1040
|
# processing and there are no busy threads on the worker.
|
|
@@ -936,7 +1046,7 @@ module Puma
|
|
|
936
1046
|
# This can be called multiple times to add several hooks.
|
|
937
1047
|
#
|
|
938
1048
|
def out_of_band(&block)
|
|
939
|
-
process_hook :out_of_band, nil, block
|
|
1049
|
+
process_hook :out_of_band, nil, block
|
|
940
1050
|
end
|
|
941
1051
|
|
|
942
1052
|
# The directory to operate out of.
|
|
@@ -950,12 +1060,13 @@ module Puma
|
|
|
950
1060
|
@options[:directory] = dir.to_s
|
|
951
1061
|
end
|
|
952
1062
|
|
|
953
|
-
# Preload the application before
|
|
954
|
-
# phased restart feature.
|
|
1063
|
+
# Preload the application before forking the workers; this conflicts with
|
|
1064
|
+
# the phased restart feature.
|
|
955
1065
|
#
|
|
956
1066
|
# The default is +true+ if your app uses more than 1 worker.
|
|
957
1067
|
#
|
|
958
1068
|
# @note Cluster mode only.
|
|
1069
|
+
# @note When using `fork_worker`, this only applies to worker 0.
|
|
959
1070
|
#
|
|
960
1071
|
# @example
|
|
961
1072
|
# preload_app!
|
|
@@ -991,6 +1102,7 @@ module Puma
|
|
|
991
1102
|
# new Bundler context and thus can float around as the release
|
|
992
1103
|
# dictates.
|
|
993
1104
|
#
|
|
1105
|
+
# @note Cluster mode only.
|
|
994
1106
|
# @note This is incompatible with +preload_app!+.
|
|
995
1107
|
# @note This is only supported for RubyGems 2.2+
|
|
996
1108
|
#
|
|
@@ -1096,7 +1208,7 @@ module Puma
|
|
|
1096
1208
|
|
|
1097
1209
|
# Change the default worker timeout for booting.
|
|
1098
1210
|
#
|
|
1099
|
-
# The default is
|
|
1211
|
+
# The default is 60 seconds.
|
|
1100
1212
|
#
|
|
1101
1213
|
# @note Cluster mode only.
|
|
1102
1214
|
#
|
|
@@ -1111,7 +1223,7 @@ module Puma
|
|
|
1111
1223
|
|
|
1112
1224
|
# Set the timeout for worker shutdown.
|
|
1113
1225
|
#
|
|
1114
|
-
# The default is
|
|
1226
|
+
# The default is 30 seconds.
|
|
1115
1227
|
#
|
|
1116
1228
|
# @note Cluster mode only.
|
|
1117
1229
|
#
|
|
@@ -1143,10 +1255,10 @@ module Puma
|
|
|
1143
1255
|
# @see Puma::Cluster#cull_workers
|
|
1144
1256
|
#
|
|
1145
1257
|
def worker_culling_strategy(strategy)
|
|
1146
|
-
|
|
1258
|
+
strategy = strategy.to_sym
|
|
1147
1259
|
|
|
1148
1260
|
if ![:youngest, :oldest].include?(strategy)
|
|
1149
|
-
raise "Invalid value for worker_culling_strategy - #{
|
|
1261
|
+
raise "Invalid value for worker_culling_strategy - #{strategy}"
|
|
1150
1262
|
end
|
|
1151
1263
|
|
|
1152
1264
|
@options[:worker_culling_strategy] = strategy
|
|
@@ -1178,24 +1290,31 @@ module Puma
|
|
|
1178
1290
|
# threads will be written to $stdout. This can help figure
|
|
1179
1291
|
# out why shutdown is hanging.
|
|
1180
1292
|
#
|
|
1181
|
-
|
|
1182
|
-
|
|
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
|
|
1183
1299
|
end
|
|
1184
1300
|
|
|
1185
|
-
|
|
1186
|
-
#
|
|
1187
|
-
#
|
|
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
|
|
1188
1305
|
# requests to pick up new requests first.
|
|
1189
1306
|
#
|
|
1190
1307
|
# The default is 0.005 seconds.
|
|
1191
1308
|
#
|
|
1192
|
-
#
|
|
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.
|
|
1193
1314
|
#
|
|
1194
1315
|
# @see Puma::Server#handle_servers
|
|
1195
1316
|
# @see Puma::ThreadPool#wait_for_less_busy_worker
|
|
1196
1317
|
#
|
|
1197
|
-
# @version 5.0.0
|
|
1198
|
-
#
|
|
1199
1318
|
def wait_for_less_busy_worker(val=0.005)
|
|
1200
1319
|
@options[:wait_for_less_busy_worker] = val.to_f
|
|
1201
1320
|
end
|
|
@@ -1269,24 +1388,31 @@ module Puma
|
|
|
1269
1388
|
# A refork will automatically trigger once after the specified number of requests
|
|
1270
1389
|
# (default 1000), or pass 0 to disable auto refork.
|
|
1271
1390
|
#
|
|
1391
|
+
# @note This is experimental.
|
|
1272
1392
|
# @note Cluster mode only.
|
|
1273
1393
|
#
|
|
1274
|
-
# @version 5.0.0
|
|
1275
|
-
#
|
|
1276
1394
|
def fork_worker(after_requests=1000)
|
|
1277
1395
|
@options[:fork_worker] = Integer(after_requests)
|
|
1278
1396
|
end
|
|
1279
1397
|
|
|
1280
|
-
#
|
|
1281
|
-
#
|
|
1398
|
+
# @deprecated Use {#max_keep_alive} instead.
|
|
1399
|
+
#
|
|
1400
|
+
def max_fast_inline(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.
|
|
1282
1408
|
#
|
|
1283
|
-
# The default is
|
|
1409
|
+
# The default is 999.
|
|
1284
1410
|
#
|
|
1285
1411
|
# @example
|
|
1286
|
-
#
|
|
1412
|
+
# max_keep_alive 20
|
|
1287
1413
|
#
|
|
1288
|
-
def
|
|
1289
|
-
@options[:
|
|
1414
|
+
def max_keep_alive(num_of_requests)
|
|
1415
|
+
@options[:max_keep_alive] = Float(num_of_requests) unless num_of_requests.nil?
|
|
1290
1416
|
end
|
|
1291
1417
|
|
|
1292
1418
|
# When `true`, keep-alive connections are maintained on inbound requests.
|
|
@@ -1328,7 +1454,7 @@ module Puma
|
|
|
1328
1454
|
#
|
|
1329
1455
|
# The default is +:auto+.
|
|
1330
1456
|
#
|
|
1331
|
-
# @see https://github.com/socketry/nio4r/blob/
|
|
1457
|
+
# @see https://github.com/socketry/nio4r/blob/main/lib/nio/selector.rb
|
|
1332
1458
|
#
|
|
1333
1459
|
def io_selector_backend(backend)
|
|
1334
1460
|
@options[:io_selector_backend] = backend.to_sym
|
|
@@ -1416,30 +1542,21 @@ module Puma
|
|
|
1416
1542
|
end
|
|
1417
1543
|
end
|
|
1418
1544
|
|
|
1419
|
-
def process_hook(options_key, key, block,
|
|
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
|
+
|
|
1420
1550
|
@options[options_key] ||= []
|
|
1421
|
-
|
|
1422
|
-
|
|
1551
|
+
hook_options = { block: block, cluster_only: cluster_only }
|
|
1552
|
+
hook_options[:id] = if ON_WORKER_KEY.include?(key.class)
|
|
1553
|
+
key.to_sym
|
|
1423
1554
|
elsif key.nil?
|
|
1424
|
-
|
|
1555
|
+
nil
|
|
1425
1556
|
else
|
|
1426
|
-
raise "'#{
|
|
1427
|
-
end
|
|
1428
|
-
end
|
|
1429
|
-
|
|
1430
|
-
def warn_if_in_single_mode(hook_name)
|
|
1431
|
-
return if @options[:silence_fork_callback_warning]
|
|
1432
|
-
# user_options (CLI) have precedence over config file
|
|
1433
|
-
workers_val = @config.options.user_options[:workers] || @options[:workers] ||
|
|
1434
|
-
@config.puma_default_options[:workers] || 0
|
|
1435
|
-
if workers_val == 0
|
|
1436
|
-
log_string =
|
|
1437
|
-
"Warning: You specified code to run in a `#{hook_name}` block, " \
|
|
1438
|
-
"but Puma is not configured to run in cluster mode (worker count > 0), " \
|
|
1439
|
-
"so your `#{hook_name}` block will not run."
|
|
1440
|
-
|
|
1441
|
-
LogWriter.stdio.log(log_string)
|
|
1557
|
+
raise "'#{options_key}' key must be String or Symbol"
|
|
1442
1558
|
end
|
|
1559
|
+
@options[options_key] << hook_options
|
|
1443
1560
|
end
|
|
1444
1561
|
end
|
|
1445
1562
|
end
|
data/lib/puma/error_logger.rb
CHANGED
|
@@ -78,10 +78,12 @@ module Puma
|
|
|
78
78
|
def request_title(req)
|
|
79
79
|
env = req.env
|
|
80
80
|
|
|
81
|
+
query_string = env[QUERY_STRING]
|
|
82
|
+
|
|
81
83
|
REQUEST_FORMAT % [
|
|
82
84
|
env[REQUEST_METHOD],
|
|
83
85
|
env[REQUEST_PATH] || env[PATH_INFO],
|
|
84
|
-
|
|
86
|
+
query_string.nil? || query_string.empty? ? "" : "?#{query_string}",
|
|
85
87
|
env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-"
|
|
86
88
|
]
|
|
87
89
|
end
|