puma 6.6.1 → 7.2.0

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 +224 -4
  3. data/README.md +34 -34
  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 +19 -19
  11. data/docs/stats.md +4 -3
  12. data/docs/systemd.md +3 -3
  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 +9 -1
  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 +52 -56
  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 +23 -23
  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 +9 -10
  28. data/lib/puma/control_cli.rb +6 -2
  29. data/lib/puma/detect.rb +2 -0
  30. data/lib/puma/dsl.rb +149 -91
  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 +42 -31
  41. data/lib/puma/runner.rb +9 -18
  42. data/lib/puma/server.rb +114 -64
  43. data/lib/puma/single.rb +6 -3
  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 +13 -5
  50. metadata +6 -5
  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,7 +659,8 @@ 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
@@ -658,21 +669,27 @@ module Puma
658
669
  @options[:state_permission] = permission
659
670
  end
660
671
 
661
- # How many worker processes to run. Typically this is set to
662
- # the number of available cores.
672
+ # How many worker processes to run. Typically this is set to the number of
673
+ # available cores.
663
674
  #
664
675
  # The default is the value of the environment variable +WEB_CONCURRENCY+ if
665
- # 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.
666
682
  #
667
- # @note Cluster mode only.
683
+ # A value of 0 or nil means run in single mode.
668
684
  #
669
685
  # @example
670
686
  # workers 2
687
+ # workers :auto
671
688
  #
672
689
  # @see Puma::Cluster
673
690
  #
674
691
  def workers(count)
675
- @options[:workers] = count.to_i
692
+ @options[:workers] = count.nil? ? 0 : @config.send(:parse_workers, count)
676
693
  end
677
694
 
678
695
  # Disable warning message when running in cluster mode with a single worker.
@@ -727,9 +744,7 @@ module Puma
727
744
  # end
728
745
  #
729
746
  def before_fork(&block)
730
- warn_if_in_single_mode('before_fork')
731
-
732
- process_hook :before_fork, nil, block, 'before_fork'
747
+ process_hook :before_fork, nil, block, cluster_only: true
733
748
  end
734
749
 
735
750
  # Code to run in a worker when it boots to setup
@@ -740,16 +755,18 @@ module Puma
740
755
  # @note Cluster mode only.
741
756
  #
742
757
  # @example
743
- # on_worker_boot do
758
+ # before_worker_boot do
744
759
  # puts 'Before worker boot...'
745
760
  # end
746
761
  #
747
- def on_worker_boot(key = nil, &block)
748
- 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__
749
764
 
750
- process_hook :before_worker_boot, key, block, 'on_worker_boot'
765
+ process_hook :before_worker_boot, key, block, cluster_only: true
751
766
  end
752
767
 
768
+ alias_method :on_worker_boot, :before_worker_boot
769
+
753
770
  # Code to run immediately before a worker shuts
754
771
  # down (after it has finished processing HTTP requests). The worker's
755
772
  # index is passed as an argument. These hooks
@@ -761,16 +778,18 @@ module Puma
761
778
  # @note Cluster mode only.
762
779
  #
763
780
  # @example
764
- # on_worker_shutdown do
781
+ # before_worker_shutdown do
765
782
  # puts 'On worker shutdown...'
766
783
  # end
767
784
  #
768
- def on_worker_shutdown(key = nil, &block)
769
- 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__
770
787
 
771
- process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown'
788
+ process_hook :before_worker_shutdown, key, block, cluster_only: true
772
789
  end
773
790
 
791
+ alias_method :on_worker_shutdown, :before_worker_shutdown
792
+
774
793
  # Code to run in the master right before a worker is started. The worker's
775
794
  # index is passed as an argument.
776
795
  #
@@ -779,16 +798,18 @@ module Puma
779
798
  # @note Cluster mode only.
780
799
  #
781
800
  # @example
782
- # on_worker_fork do
801
+ # before_worker_fork do
783
802
  # puts 'Before worker fork...'
784
803
  # end
785
804
  #
786
- def on_worker_fork(&block)
787
- warn_if_in_single_mode('on_worker_fork')
805
+ def before_worker_fork(&block)
806
+ Puma.deprecate_method_change :on_worker_fork, __callee__, __method__
788
807
 
789
- process_hook :before_worker_fork, nil, block, 'on_worker_fork'
808
+ process_hook :before_worker_fork, nil, block, cluster_only: true
790
809
  end
791
810
 
811
+ alias_method :on_worker_fork, :before_worker_fork
812
+
792
813
  # Code to run in the master after a worker has been started. The worker's
793
814
  # index is passed as an argument.
794
815
  #
@@ -802,34 +823,53 @@ module Puma
802
823
  # end
803
824
  #
804
825
  def after_worker_fork(&block)
805
- warn_if_in_single_mode('after_worker_fork')
806
-
807
- process_hook :after_worker_fork, nil, block, 'after_worker_fork'
826
+ process_hook :after_worker_fork, nil, block, cluster_only: true
808
827
  end
809
828
 
810
829
  alias_method :after_worker_boot, :after_worker_fork
811
830
 
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
+
812
845
  # Code to run after puma is booted (works for both single and cluster modes).
813
846
  #
814
847
  # @example
815
- # on_booted do
848
+ # after_booted do
816
849
  # puts 'After booting...'
817
850
  # end
818
851
  #
819
- def on_booted(&block)
820
- @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)
821
856
  end
822
857
 
823
- # Code to run after puma is stopped (works for both single and cluster modes).
858
+ alias_method :on_booted, :after_booted
859
+
860
+ # Code to run after puma is stopped (works for both: single and clustered)
824
861
  #
825
862
  # @example
826
- # on_stopped do
863
+ # after_stopped do
827
864
  # puts 'After stopping...'
828
865
  # end
829
866
  #
830
- def on_stopped(&block)
831
- @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)
832
871
  end
872
+ alias_method :on_stopped, :after_stopped
833
873
 
834
874
  # When `fork_worker` is enabled, code to run in Worker 0
835
875
  # before all other workers are re-forked from this process,
@@ -845,23 +885,27 @@ module Puma
845
885
  # @note Cluster mode with `fork_worker` enabled only.
846
886
  #
847
887
  # @example
848
- # on_refork do
888
+ # before_refork do
849
889
  # 3.times {GC.start}
850
890
  # end
851
891
  #
852
- def on_refork(key = nil, &block)
853
- warn_if_in_single_mode('on_refork')
892
+ # @version 5.0.0
893
+ #
894
+ def before_refork(key = nil, &block)
895
+ Puma.deprecate_method_change :on_refork, __callee__, __method__
854
896
 
855
- process_hook :before_refork, key, block, 'on_refork'
897
+ process_hook :before_refork, key, block, cluster_only: true
856
898
  end
857
899
 
900
+ alias_method :on_refork, :before_refork
901
+
858
902
  # When `fork_worker` is enabled, code to run in Worker 0
859
903
  # after all other workers are re-forked from this process,
860
904
  # after the server has temporarily stopped serving requests
861
905
  # (once per complete refork cycle).
862
906
  #
863
907
  # This can be used to re-open any connections to remote servers
864
- # (database, Redis, ...) that were closed via on_refork.
908
+ # (database, Redis, ...) that were closed via before_refork.
865
909
  #
866
910
  # This can be called multiple times to add several hooks.
867
911
  #
@@ -873,7 +917,7 @@ module Puma
873
917
  # end
874
918
  #
875
919
  def after_refork(key = nil, &block)
876
- process_hook :after_refork, key, block, 'after_refork'
920
+ process_hook :after_refork, key, block
877
921
  end
878
922
 
879
923
  # Provide a block to be executed just before a thread is added to the thread
@@ -889,14 +933,18 @@ module Puma
889
933
  # This can be called multiple times to add several hooks.
890
934
  #
891
935
  # @example
892
- # on_thread_start do
936
+ # before_thread_start do
893
937
  # puts 'On thread start...'
894
938
  # end
895
939
  #
896
- def on_thread_start(&block)
897
- 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
898
944
  end
899
945
 
946
+ alias_method :on_thread_start, :before_thread_start
947
+
900
948
  # Provide a block to be executed after a thread is trimmed from the thread
901
949
  # pool. Be careful: while this block executes, Puma's main loop is
902
950
  # blocked, so no new requests will be picked up.
@@ -913,14 +961,18 @@ module Puma
913
961
  # This can be called multiple times to add several hooks.
914
962
  #
915
963
  # @example
916
- # on_thread_exit do
964
+ # before_thread_exit do
917
965
  # puts 'On thread exit...'
918
966
  # end
919
967
  #
920
- def on_thread_exit(&block)
921
- 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
922
972
  end
923
973
 
974
+ alias_method :on_thread_exit, :before_thread_exit
975
+
924
976
  # Code to run out-of-band when the worker is idle.
925
977
  # These hooks run immediately after a request has finished
926
978
  # processing and there are no busy threads on the worker.
@@ -932,7 +984,7 @@ module Puma
932
984
  # This can be called multiple times to add several hooks.
933
985
  #
934
986
  def out_of_band(&block)
935
- process_hook :out_of_band, nil, block, 'out_of_band'
987
+ process_hook :out_of_band, nil, block
936
988
  end
937
989
 
938
990
  # The directory to operate out of.
@@ -946,12 +998,13 @@ module Puma
946
998
  @options[:directory] = dir.to_s
947
999
  end
948
1000
 
949
- # Preload the application before starting the workers; this conflicts with
950
- # phased restart feature.
1001
+ # Preload the application before forking the workers; this conflicts with
1002
+ # the phased restart feature.
951
1003
  #
952
1004
  # The default is +true+ if your app uses more than 1 worker.
953
1005
  #
954
1006
  # @note Cluster mode only.
1007
+ # @note When using `fork_worker`, this only applies to worker 0.
955
1008
  #
956
1009
  # @example
957
1010
  # preload_app!
@@ -1179,13 +1232,19 @@ module Puma
1179
1232
  end
1180
1233
 
1181
1234
 
1182
- # Attempts to route traffic to less-busy workers by causing them to delay
1183
- # 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
1184
1239
  # requests to pick up new requests first.
1185
1240
  #
1186
1241
  # The default is 0.005 seconds.
1187
1242
  #
1188
- # 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.
1189
1248
  #
1190
1249
  # @see Puma::Server#handle_servers
1191
1250
  # @see Puma::ThreadPool#wait_for_less_busy_worker
@@ -1270,16 +1329,24 @@ module Puma
1270
1329
  @options[:fork_worker] = Integer(after_requests)
1271
1330
  end
1272
1331
 
1273
- # The number of requests to attempt inline before sending a client back to
1274
- # 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.
1275
1342
  #
1276
- # The default is 10.
1343
+ # The default is 999.
1277
1344
  #
1278
1345
  # @example
1279
- # max_fast_inline 20
1346
+ # max_keep_alive 20
1280
1347
  #
1281
- def max_fast_inline(num_of_requests)
1282
- @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?
1283
1350
  end
1284
1351
 
1285
1352
  # When `true`, keep-alive connections are maintained on inbound requests.
@@ -1321,7 +1388,7 @@ module Puma
1321
1388
  #
1322
1389
  # The default is +:auto+.
1323
1390
  #
1324
- # @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
1325
1392
  #
1326
1393
  def io_selector_backend(backend)
1327
1394
  @options[:io_selector_backend] = backend.to_sym
@@ -1409,30 +1476,21 @@ module Puma
1409
1476
  end
1410
1477
  end
1411
1478
 
1412
- 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
+
1413
1484
  @options[options_key] ||= []
1414
- if ON_WORKER_KEY.include? key.class
1415
- @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
1416
1488
  elsif key.nil?
1417
- @options[options_key] << block
1489
+ nil
1418
1490
  else
1419
- raise "'#{meth}' key must be String or Symbol"
1420
- end
1421
- end
1422
-
1423
- def warn_if_in_single_mode(hook_name)
1424
- return if @options[:silence_fork_callback_warning]
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
1429
- log_string =
1430
- "Warning: You specified code to run in a `#{hook_name}` block, " \
1431
- "but Puma is not configured to run in cluster mode (worker count > 0), " \
1432
- "so your `#{hook_name}` block will not run."
1433
-
1434
- LogWriter.stdio.log(log_string)
1491
+ raise "'#{options_key}' key must be String or Symbol"
1435
1492
  end
1493
+ @options[options_key] << hook_options
1436
1494
  end
1437
1495
  end
1438
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