puma 6.6.0 → 7.2.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +248 -5
  3. data/README.md +40 -40
  4. data/docs/deployment.md +58 -23
  5. data/docs/fork_worker.md +5 -5
  6. data/docs/jungle/README.md +1 -1
  7. data/docs/kubernetes.md +11 -16
  8. data/docs/plugins.md +2 -2
  9. data/docs/restart.md +2 -2
  10. data/docs/signals.md +21 -21
  11. data/docs/stats.md +4 -3
  12. data/docs/systemd.md +4 -4
  13. data/ext/puma_http11/extconf.rb +2 -17
  14. data/ext/puma_http11/mini_ssl.c +18 -8
  15. data/ext/puma_http11/org/jruby/puma/Http11.java +10 -2
  16. data/ext/puma_http11/puma_http11.c +122 -118
  17. data/lib/puma/app/status.rb +10 -2
  18. data/lib/puma/binder.rb +10 -8
  19. data/lib/puma/cli.rb +3 -5
  20. data/lib/puma/client.rb +122 -72
  21. data/lib/puma/cluster/worker.rb +17 -17
  22. data/lib/puma/cluster/worker_handle.rb +38 -7
  23. data/lib/puma/cluster.rb +43 -29
  24. data/lib/puma/cluster_accept_loop_delay.rb +91 -0
  25. data/lib/puma/commonlogger.rb +3 -3
  26. data/lib/puma/configuration.rb +104 -51
  27. data/lib/puma/const.rb +11 -11
  28. data/lib/puma/control_cli.rb +6 -2
  29. data/lib/puma/detect.rb +2 -0
  30. data/lib/puma/dsl.rb +151 -100
  31. data/lib/puma/error_logger.rb +3 -1
  32. data/lib/puma/events.rb +25 -10
  33. data/lib/puma/io_buffer.rb +8 -4
  34. data/lib/puma/launcher/bundle_pruner.rb +1 -1
  35. data/lib/puma/launcher.rb +54 -49
  36. data/lib/puma/minissl.rb +0 -1
  37. data/lib/puma/plugin/systemd.rb +3 -3
  38. data/lib/puma/rack/urlmap.rb +1 -1
  39. data/lib/puma/reactor.rb +19 -13
  40. data/lib/puma/request.rb +54 -39
  41. data/lib/puma/runner.rb +9 -18
  42. data/lib/puma/server.rb +114 -64
  43. data/lib/puma/single.rb +7 -4
  44. data/lib/puma/state_file.rb +3 -2
  45. data/lib/puma/thread_pool.rb +47 -82
  46. data/lib/puma/util.rb +0 -7
  47. data/lib/puma.rb +10 -0
  48. data/lib/rack/handler/puma.rb +2 -2
  49. data/tools/Dockerfile +15 -5
  50. metadata +7 -6
  51. 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,11 +43,11 @@ 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 |
50
- # | after_refork | :after_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 |
51
51
  #
52
52
  class DSL
53
53
  ON_WORKER_KEY = [String, Symbol].freeze
@@ -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.
@@ -370,18 +373,21 @@ module Puma
370
373
  @options[:idle_timeout] = Integer(seconds)
371
374
  end
372
375
 
373
- # Work around leaky apps that leave garbage in Thread locals
374
- # across requests.
376
+ # Use a clean fiber per request which ensures a clean slate for fiber
377
+ # locals and fiber storage. Also provides a cleaner backtrace with less
378
+ # Puma internal stack frames.
375
379
  #
376
380
  # The default is +false+.
377
381
  #
378
382
  # @example
379
- # clean_thread_locals
383
+ # fiber_per_request
380
384
  #
381
- def clean_thread_locals(which=true)
382
- @options[:clean_thread_locals] = which
385
+ def fiber_per_request(which=true)
386
+ @options[:fiber_per_request] = which
383
387
  end
384
388
 
389
+ alias clean_thread_locals fiber_per_request
390
+
385
391
  # When shutting down, drain the accept socket of pending connections and
386
392
  # process them. This loops over the accept socket until there are no more
387
393
  # read events and then stops looking and waits for the requests to finish.
@@ -434,14 +440,18 @@ module Puma
434
440
  # This can be called multiple times to add code each time.
435
441
  #
436
442
  # @example
437
- # on_restart do
443
+ # before_restart do
438
444
  # puts 'On restart...'
439
445
  # end
440
446
  #
441
- def on_restart(&block)
442
- process_hook :on_restart, nil, block, 'on_restart'
447
+ def before_restart(&block)
448
+ Puma.deprecate_method_change :on_restart, __callee__, __method__
449
+
450
+ process_hook :before_restart, nil, block
443
451
  end
444
452
 
453
+ alias_method :on_restart, :before_restart
454
+
445
455
  # Command to use to restart Puma. This should be just how to
446
456
  # load Puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments
447
457
  # to Puma, as those are the same as the original process.
@@ -649,32 +659,37 @@ module Puma
649
659
  @options[:state] = path.to_s
650
660
  end
651
661
 
652
- # Use +permission+ to restrict permissions for the state file.
662
+ # Use +permission+ to restrict permissions for the state file. By convention,
663
+ # +permission+ is an octal number (e.g. `0640` or `0o640`).
653
664
  #
654
665
  # @example
655
666
  # state_permission 0600
656
667
  #
657
- # @version 5.0.0
658
- #
659
668
  def state_permission(permission)
660
669
  @options[:state_permission] = permission
661
670
  end
662
671
 
663
- # How many worker processes to run. Typically this is set to
664
- # the number of available cores.
672
+ # How many worker processes to run. Typically this is set to the number of
673
+ # available cores.
665
674
  #
666
675
  # The default is the value of the environment variable +WEB_CONCURRENCY+ if
667
- # set, otherwise 0.
676
+ # set, otherwise 0. Passing +:auto+ will set the value to
677
+ # +Concurrent.available_processor_count+ (requires the concurrent-ruby gem).
678
+ # On some platforms (e.g. under CPU quotas) this may be fractional, and Puma
679
+ # will round down. If it rounds down to 0, Puma will run in single mode and
680
+ # cluster-only hooks like +before_worker_boot+ will not execute.
681
+ # If you rely on cluster-only hooks, set an explicit worker count.
668
682
  #
669
- # @note Cluster mode only.
683
+ # A value of 0 or nil means run in single mode.
670
684
  #
671
685
  # @example
672
686
  # workers 2
687
+ # workers :auto
673
688
  #
674
689
  # @see Puma::Cluster
675
690
  #
676
691
  def workers(count)
677
- @options[:workers] = count.to_i
692
+ @options[:workers] = count.nil? ? 0 : @config.send(:parse_workers, count)
678
693
  end
679
694
 
680
695
  # Disable warning message when running in cluster mode with a single worker.
@@ -729,9 +744,7 @@ module Puma
729
744
  # end
730
745
  #
731
746
  def before_fork(&block)
732
- warn_if_in_single_mode('before_fork')
733
-
734
- process_hook :before_fork, nil, block, 'before_fork'
747
+ process_hook :before_fork, nil, block, cluster_only: true
735
748
  end
736
749
 
737
750
  # Code to run in a worker when it boots to setup
@@ -742,16 +755,18 @@ module Puma
742
755
  # @note Cluster mode only.
743
756
  #
744
757
  # @example
745
- # on_worker_boot do
758
+ # before_worker_boot do
746
759
  # puts 'Before worker boot...'
747
760
  # end
748
761
  #
749
- def on_worker_boot(key = nil, &block)
750
- warn_if_in_single_mode('on_worker_boot')
762
+ def before_worker_boot(key = nil, &block)
763
+ Puma.deprecate_method_change :on_worker_boot, __callee__, __method__
751
764
 
752
- process_hook :before_worker_boot, key, block, 'on_worker_boot'
765
+ process_hook :before_worker_boot, key, block, cluster_only: true
753
766
  end
754
767
 
768
+ alias_method :on_worker_boot, :before_worker_boot
769
+
755
770
  # Code to run immediately before a worker shuts
756
771
  # down (after it has finished processing HTTP requests). The worker's
757
772
  # index is passed as an argument. These hooks
@@ -763,16 +778,18 @@ module Puma
763
778
  # @note Cluster mode only.
764
779
  #
765
780
  # @example
766
- # on_worker_shutdown do
781
+ # before_worker_shutdown do
767
782
  # puts 'On worker shutdown...'
768
783
  # end
769
784
  #
770
- def on_worker_shutdown(key = nil, &block)
771
- warn_if_in_single_mode('on_worker_shutdown')
785
+ def before_worker_shutdown(key = nil, &block)
786
+ Puma.deprecate_method_change :on_worker_shutdown, __callee__, __method__
772
787
 
773
- process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
788
+ process_hook :before_worker_shutdown, key, block, cluster_only: true
774
789
  end
775
790
 
791
+ alias_method :on_worker_shutdown, :before_worker_shutdown
792
+
776
793
  # Code to run in the master right before a worker is started. The worker's
777
794
  # index is passed as an argument.
778
795
  #
@@ -781,16 +798,18 @@ module Puma
781
798
  # @note Cluster mode only.
782
799
  #
783
800
  # @example
784
- # on_worker_fork do
801
+ # before_worker_fork do
785
802
  # puts 'Before worker fork...'
786
803
  # end
787
804
  #
788
- def on_worker_fork(&block)
789
- warn_if_in_single_mode('on_worker_fork')
805
+ def before_worker_fork(&block)
806
+ Puma.deprecate_method_change :on_worker_fork, __callee__, __method__
790
807
 
791
- process_hook :before_worker_fork, nil, block, 'on_worker_fork'
808
+ process_hook :before_worker_fork, nil, block, cluster_only: true
792
809
  end
793
810
 
811
+ alias_method :on_worker_fork, :before_worker_fork
812
+
794
813
  # Code to run in the master after a worker has been started. The worker's
795
814
  # index is passed as an argument.
796
815
  #
@@ -804,34 +823,53 @@ module Puma
804
823
  # end
805
824
  #
806
825
  def after_worker_fork(&block)
807
- warn_if_in_single_mode('after_worker_fork')
808
-
809
- process_hook :after_worker_fork, nil, block, 'after_worker_fork'
826
+ process_hook :after_worker_fork, nil, block, cluster_only: true
810
827
  end
811
828
 
812
829
  alias_method :after_worker_boot, :after_worker_fork
813
830
 
814
- # Code to run after puma is booted (works for both: single and clustered)
831
+ # Code to run in the master right after a worker has stopped. The worker's
832
+ # index and Process::Status are passed as arguments.
833
+ #
834
+ # @note Cluster mode only.
835
+ #
836
+ # @example
837
+ # after_worker_shutdown do |worker_handle|
838
+ # puts 'Worker crashed' unless worker_handle.process_status.success?
839
+ # end
840
+ #
841
+ def after_worker_shutdown(&block)
842
+ process_hook :after_worker_shutdown, nil, block, cluster_only: true
843
+ end
844
+
845
+ # Code to run after puma is booted (works for both single and cluster modes).
815
846
  #
816
847
  # @example
817
- # on_booted do
848
+ # after_booted do
818
849
  # puts 'After booting...'
819
850
  # end
820
851
  #
821
- def on_booted(&block)
822
- @config.options[:events].on_booted(&block)
852
+ def after_booted(&block)
853
+ Puma.deprecate_method_change :on_booted, __callee__, __method__
854
+
855
+ @config.events.after_booted(&block)
823
856
  end
824
857
 
858
+ alias_method :on_booted, :after_booted
859
+
825
860
  # Code to run after puma is stopped (works for both: single and clustered)
826
861
  #
827
862
  # @example
828
- # on_stopped do
863
+ # after_stopped do
829
864
  # puts 'After stopping...'
830
865
  # end
831
866
  #
832
- def on_stopped(&block)
833
- @config.options[:events].on_stopped(&block)
867
+ def after_stopped(&block)
868
+ Puma.deprecate_method_change :on_stopped, __callee__, __method__
869
+
870
+ @config.events.after_stopped(&block)
834
871
  end
872
+ alias_method :on_stopped, :after_stopped
835
873
 
836
874
  # When `fork_worker` is enabled, code to run in Worker 0
837
875
  # before all other workers are re-forked from this process,
@@ -847,25 +885,27 @@ module Puma
847
885
  # @note Cluster mode with `fork_worker` enabled only.
848
886
  #
849
887
  # @example
850
- # on_refork do
888
+ # before_refork do
851
889
  # 3.times {GC.start}
852
890
  # end
853
891
  #
854
892
  # @version 5.0.0
855
893
  #
856
- def on_refork(key = nil, &block)
857
- warn_if_in_single_mode('on_refork')
894
+ def before_refork(key = nil, &block)
895
+ Puma.deprecate_method_change :on_refork, __callee__, __method__
858
896
 
859
- process_hook :before_refork, key, block, 'on_refork'
897
+ process_hook :before_refork, key, block, cluster_only: true
860
898
  end
861
899
 
900
+ alias_method :on_refork, :before_refork
901
+
862
902
  # When `fork_worker` is enabled, code to run in Worker 0
863
903
  # after all other workers are re-forked from this process,
864
904
  # after the server has temporarily stopped serving requests
865
905
  # (once per complete refork cycle).
866
906
  #
867
907
  # This can be used to re-open any connections to remote servers
868
- # (database, Redis, ...) that were closed via on_refork.
908
+ # (database, Redis, ...) that were closed via before_refork.
869
909
  #
870
910
  # This can be called multiple times to add several hooks.
871
911
  #
@@ -877,7 +917,7 @@ module Puma
877
917
  # end
878
918
  #
879
919
  def after_refork(key = nil, &block)
880
- process_hook :after_refork, key, block, 'after_refork'
920
+ process_hook :after_refork, key, block
881
921
  end
882
922
 
883
923
  # Provide a block to be executed just before a thread is added to the thread
@@ -893,14 +933,18 @@ module Puma
893
933
  # This can be called multiple times to add several hooks.
894
934
  #
895
935
  # @example
896
- # on_thread_start do
936
+ # before_thread_start do
897
937
  # puts 'On thread start...'
898
938
  # end
899
939
  #
900
- def on_thread_start(&block)
901
- process_hook :before_thread_start, nil, block, 'on_thread_start'
940
+ def before_thread_start(&block)
941
+ Puma.deprecate_method_change :on_thread_start, __callee__, __method__
942
+
943
+ process_hook :before_thread_start, nil, block
902
944
  end
903
945
 
946
+ alias_method :on_thread_start, :before_thread_start
947
+
904
948
  # Provide a block to be executed after a thread is trimmed from the thread
905
949
  # pool. Be careful: while this block executes, Puma's main loop is
906
950
  # blocked, so no new requests will be picked up.
@@ -917,14 +961,18 @@ module Puma
917
961
  # This can be called multiple times to add several hooks.
918
962
  #
919
963
  # @example
920
- # on_thread_exit do
964
+ # before_thread_exit do
921
965
  # puts 'On thread exit...'
922
966
  # end
923
967
  #
924
- def on_thread_exit(&block)
925
- process_hook :before_thread_exit, nil, block, 'on_thread_exit'
968
+ def before_thread_exit(&block)
969
+ Puma.deprecate_method_change :on_thread_exit, __callee__, __method__
970
+
971
+ process_hook :before_thread_exit, nil, block
926
972
  end
927
973
 
974
+ alias_method :on_thread_exit, :before_thread_exit
975
+
928
976
  # Code to run out-of-band when the worker is idle.
929
977
  # These hooks run immediately after a request has finished
930
978
  # processing and there are no busy threads on the worker.
@@ -936,7 +984,7 @@ module Puma
936
984
  # This can be called multiple times to add several hooks.
937
985
  #
938
986
  def out_of_band(&block)
939
- process_hook :out_of_band, nil, block, 'out_of_band'
987
+ process_hook :out_of_band, nil, block
940
988
  end
941
989
 
942
990
  # The directory to operate out of.
@@ -950,12 +998,13 @@ module Puma
950
998
  @options[:directory] = dir.to_s
951
999
  end
952
1000
 
953
- # Preload the application before starting the workers; this conflicts with
954
- # phased restart feature.
1001
+ # Preload the application before forking the workers; this conflicts with
1002
+ # the phased restart feature.
955
1003
  #
956
1004
  # The default is +true+ if your app uses more than 1 worker.
957
1005
  #
958
1006
  # @note Cluster mode only.
1007
+ # @note When using `fork_worker`, this only applies to worker 0.
959
1008
  #
960
1009
  # @example
961
1010
  # preload_app!
@@ -1111,7 +1160,7 @@ module Puma
1111
1160
 
1112
1161
  # Set the timeout for worker shutdown.
1113
1162
  #
1114
- # The default is 60 seconds.
1163
+ # The default is 30 seconds.
1115
1164
  #
1116
1165
  # @note Cluster mode only.
1117
1166
  #
@@ -1143,10 +1192,10 @@ module Puma
1143
1192
  # @see Puma::Cluster#cull_workers
1144
1193
  #
1145
1194
  def worker_culling_strategy(strategy)
1146
- stategy = strategy.to_sym
1195
+ strategy = strategy.to_sym
1147
1196
 
1148
1197
  if ![:youngest, :oldest].include?(strategy)
1149
- raise "Invalid value for worker_culling_strategy - #{stategy}"
1198
+ raise "Invalid value for worker_culling_strategy - #{strategy}"
1150
1199
  end
1151
1200
 
1152
1201
  @options[:worker_culling_strategy] = strategy
@@ -1183,19 +1232,23 @@ module Puma
1183
1232
  end
1184
1233
 
1185
1234
 
1186
- # Attempts to route traffic to less-busy workers by causing them to delay
1187
- # listening on the socket, allowing workers which are not processing any
1235
+ # Maximum delay of worker accept loop.
1236
+ #
1237
+ # Attempts to route traffic to less-busy workers by causing a busy worker to delay
1238
+ # listening on the socket, allowing workers which are not processing as many
1188
1239
  # requests to pick up new requests first.
1189
1240
  #
1190
1241
  # The default is 0.005 seconds.
1191
1242
  #
1192
- # Only works on MRI. For all other interpreters, this setting does nothing.
1243
+ # To turn off this feature, set the value to 0.
1244
+ #
1245
+ # @note Cluster mode with >= 2 workers only.
1246
+ #
1247
+ # @note Interpreters with forking support only.
1193
1248
  #
1194
1249
  # @see Puma::Server#handle_servers
1195
1250
  # @see Puma::ThreadPool#wait_for_less_busy_worker
1196
1251
  #
1197
- # @version 5.0.0
1198
- #
1199
1252
  def wait_for_less_busy_worker(val=0.005)
1200
1253
  @options[:wait_for_less_busy_worker] = val.to_f
1201
1254
  end
@@ -1269,24 +1322,31 @@ module Puma
1269
1322
  # A refork will automatically trigger once after the specified number of requests
1270
1323
  # (default 1000), or pass 0 to disable auto refork.
1271
1324
  #
1325
+ # @note This is experimental.
1272
1326
  # @note Cluster mode only.
1273
1327
  #
1274
- # @version 5.0.0
1275
- #
1276
1328
  def fork_worker(after_requests=1000)
1277
1329
  @options[:fork_worker] = Integer(after_requests)
1278
1330
  end
1279
1331
 
1280
- # The number of requests to attempt inline before sending a client back to
1281
- # the reactor to be subject to normal ordering.
1332
+ # @deprecated Use {#max_keep_alive} instead.
1333
+ #
1334
+ def max_fast_inline(num_of_requests)
1335
+ Puma.deprecate_method_change :max_fast_inline, __method__, :max_keep_alive
1336
+ @options[:max_keep_alive] ||= Float(num_of_requests) unless num_of_requests.nil?
1337
+ end
1338
+
1339
+ # The number of requests a keep-alive client can submit before being closed.
1340
+ # Note that some applications (server to server) may benefit from a very high
1341
+ # number or Float::INFINITY.
1282
1342
  #
1283
- # The default is 10.
1343
+ # The default is 999.
1284
1344
  #
1285
1345
  # @example
1286
- # max_fast_inline 20
1346
+ # max_keep_alive 20
1287
1347
  #
1288
- def max_fast_inline(num_of_requests)
1289
- @options[:max_fast_inline] = Float(num_of_requests)
1348
+ def max_keep_alive(num_of_requests)
1349
+ @options[:max_keep_alive] = Float(num_of_requests) unless num_of_requests.nil?
1290
1350
  end
1291
1351
 
1292
1352
  # When `true`, keep-alive connections are maintained on inbound requests.
@@ -1328,7 +1388,7 @@ module Puma
1328
1388
  #
1329
1389
  # The default is +:auto+.
1330
1390
  #
1331
- # @see https://github.com/socketry/nio4r/blob/master/lib/nio/selector.rb
1391
+ # @see https://github.com/socketry/nio4r/blob/main/lib/nio/selector.rb
1332
1392
  #
1333
1393
  def io_selector_backend(backend)
1334
1394
  @options[:io_selector_backend] = backend.to_sym
@@ -1416,30 +1476,21 @@ module Puma
1416
1476
  end
1417
1477
  end
1418
1478
 
1419
- def process_hook(options_key, key, block, meth)
1479
+ def process_hook(options_key, key, block, cluster_only: false)
1480
+ raise ArgumentError, "expected #{options_key} to be given a block" unless block
1481
+
1482
+ @config.hooks[options_key] = true
1483
+
1420
1484
  @options[options_key] ||= []
1421
- if ON_WORKER_KEY.include? key.class
1422
- @options[options_key] << [block, key.to_sym]
1485
+ hook_options = { block: block, cluster_only: cluster_only }
1486
+ hook_options[:id] = if ON_WORKER_KEY.include?(key.class)
1487
+ key.to_sym
1423
1488
  elsif key.nil?
1424
- @options[options_key] << block
1489
+ nil
1425
1490
  else
1426
- raise "'#{meth}' key must be String or Symbol"
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)
1491
+ raise "'#{options_key}' key must be String or Symbol"
1442
1492
  end
1493
+ @options[options_key] << hook_options
1443
1494
  end
1444
1495
  end
1445
1496
  end
@@ -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
- env[QUERY_STRING] || "",
86
+ query_string.nil? || query_string.empty? ? "" : "?#{query_string}",
85
87
  env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-"
86
88
  ]
87
89
  end
data/lib/puma/events.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Puma
4
4
 
5
5
  # This is an event sink used by `Puma::Server` to handle
6
- # lifecycle events such as :on_booted, :on_restart, and :on_stopped.
6
+ # lifecycle events such as :after_booted, :before_restart, and :after_stopped.
7
7
  # Using `Puma::DSL` it is possible to register callback hooks
8
8
  # for each event type.
9
9
  class Events
@@ -30,28 +30,43 @@ module Puma
30
30
  h
31
31
  end
32
32
 
33
+ def after_booted(&block)
34
+ register(:after_booted, &block)
35
+ end
36
+
37
+ def before_restart(&block)
38
+ register(:before_restart, &block)
39
+ end
40
+
41
+ def after_stopped(&block)
42
+ register(:after_stopped, &block)
43
+ end
44
+
33
45
  def on_booted(&block)
34
- register(:on_booted, &block)
46
+ Puma.deprecate_method_change :on_booted, __callee__, :after_booted
47
+ after_booted(&block)
35
48
  end
36
49
 
37
50
  def on_restart(&block)
38
- register(:on_restart, &block)
51
+ Puma.deprecate_method_change :on_restart, __callee__, :before_restart
52
+ before_restart(&block)
39
53
  end
40
54
 
41
55
  def on_stopped(&block)
42
- register(:on_stopped, &block)
56
+ Puma.deprecate_method_change :on_stopped, __callee__, :after_stopped
57
+ after_stopped(&block)
43
58
  end
44
59
 
45
- def fire_on_booted!
46
- fire(:on_booted)
60
+ def fire_after_booted!
61
+ fire(:after_booted)
47
62
  end
48
63
 
49
- def fire_on_restart!
50
- fire(:on_restart)
64
+ def fire_before_restart!
65
+ fire(:before_restart)
51
66
  end
52
67
 
53
- def fire_on_stopped!
54
- fire(:on_stopped)
68
+ def fire_after_stopped!
69
+ fire(:after_stopped)
55
70
  end
56
71
  end
57
72
  end
@@ -34,13 +34,17 @@ module Puma
34
34
 
35
35
  alias_method :clear, :reset
36
36
 
37
- # before Ruby 2.5, `write` would only take one argument
38
- if RUBY_VERSION >= '2.5' && RUBY_ENGINE != 'truffleruby'
39
- alias_method :append, :write
40
- else
37
+ # Create an `IoBuffer#append` method that accepts multiple strings and writes them
38
+ if RUBY_ENGINE == 'truffleruby'
39
+ # truffleruby (24.2.1, like ruby 3.3.7)
40
+ # StringIO.new.write("a", "b") # => `write': wrong number of arguments (given 2, expected 1) (ArgumentError)
41
41
  def append(*strs)
42
42
  strs.each { |str| write str }
43
43
  end
44
+ else
45
+ # Ruby 3+
46
+ # StringIO.new.write("a", "b") # => 2
47
+ alias_method :append, :write
44
48
  end
45
49
  end
46
50
  end
@@ -37,7 +37,7 @@ module Puma
37
37
  ENV['PUMA_BUNDLER_PRUNED'] = '1'
38
38
  ENV["BUNDLE_APP_CONFIG"] = bundle_app_config
39
39
  args = [Gem.ruby, puma_wild_path, '-I', dirs.join(':')] + @original_argv
40
- # Ruby 2.0+ defaults to true which breaks socket activation
40
+ # Defaults to true which breaks socket activation
41
41
  args += [{:close_others => false}]
42
42
  Kernel.exec(*args)
43
43
  end