puma 3.11.1 → 6.6.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 (98) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +2092 -422
  3. data/LICENSE +23 -20
  4. data/README.md +301 -69
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +59 -21
  7. data/docs/compile_options.md +55 -0
  8. data/docs/deployment.md +69 -58
  9. data/docs/fork_worker.md +41 -0
  10. data/docs/java_options.md +54 -0
  11. data/docs/jungle/README.md +9 -0
  12. data/docs/jungle/rc.d/README.md +74 -0
  13. data/docs/jungle/rc.d/puma +61 -0
  14. data/docs/jungle/rc.d/puma.conf +10 -0
  15. data/docs/kubernetes.md +78 -0
  16. data/docs/nginx.md +2 -2
  17. data/docs/plugins.md +26 -12
  18. data/docs/rails_dev_mode.md +28 -0
  19. data/docs/restart.md +48 -22
  20. data/docs/signals.md +13 -11
  21. data/docs/stats.md +147 -0
  22. data/docs/systemd.md +108 -117
  23. data/docs/testing_benchmarks_local_files.md +150 -0
  24. data/docs/testing_test_rackup_ci_files.md +36 -0
  25. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  26. data/ext/puma_http11/ext_help.h +1 -1
  27. data/ext/puma_http11/extconf.rb +68 -3
  28. data/ext/puma_http11/http11_parser.c +106 -118
  29. data/ext/puma_http11/http11_parser.h +2 -2
  30. data/ext/puma_http11/http11_parser.java.rl +22 -38
  31. data/ext/puma_http11/http11_parser.rl +6 -4
  32. data/ext/puma_http11/http11_parser_common.rl +6 -6
  33. data/ext/puma_http11/mini_ssl.c +474 -94
  34. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  35. data/ext/puma_http11/org/jruby/puma/Http11.java +136 -121
  36. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +84 -99
  37. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +251 -88
  38. data/ext/puma_http11/puma_http11.c +53 -58
  39. data/lib/puma/app/status.rb +71 -49
  40. data/lib/puma/binder.rb +257 -151
  41. data/lib/puma/cli.rb +61 -38
  42. data/lib/puma/client.rb +464 -224
  43. data/lib/puma/cluster/worker.rb +183 -0
  44. data/lib/puma/cluster/worker_handle.rb +96 -0
  45. data/lib/puma/cluster.rb +343 -239
  46. data/lib/puma/commonlogger.rb +23 -14
  47. data/lib/puma/configuration.rb +144 -96
  48. data/lib/puma/const.rb +194 -115
  49. data/lib/puma/control_cli.rb +135 -81
  50. data/lib/puma/detect.rb +34 -2
  51. data/lib/puma/dsl.rb +1092 -153
  52. data/lib/puma/error_logger.rb +113 -0
  53. data/lib/puma/events.rb +17 -111
  54. data/lib/puma/io_buffer.rb +44 -5
  55. data/lib/puma/jruby_restart.rb +2 -73
  56. data/lib/puma/json_serialization.rb +96 -0
  57. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  58. data/lib/puma/launcher.rb +205 -138
  59. data/lib/puma/log_writer.rb +147 -0
  60. data/lib/puma/minissl/context_builder.rb +96 -0
  61. data/lib/puma/minissl.rb +279 -70
  62. data/lib/puma/null_io.rb +61 -2
  63. data/lib/puma/plugin/systemd.rb +90 -0
  64. data/lib/puma/plugin/tmp_restart.rb +3 -1
  65. data/lib/puma/plugin.rb +9 -13
  66. data/lib/puma/rack/builder.rb +10 -11
  67. data/lib/puma/rack/urlmap.rb +3 -1
  68. data/lib/puma/rack_default.rb +21 -4
  69. data/lib/puma/reactor.rb +97 -185
  70. data/lib/puma/request.rb +688 -0
  71. data/lib/puma/runner.rb +114 -69
  72. data/lib/puma/sd_notify.rb +146 -0
  73. data/lib/puma/server.rb +409 -704
  74. data/lib/puma/single.rb +29 -72
  75. data/lib/puma/state_file.rb +48 -9
  76. data/lib/puma/thread_pool.rb +234 -93
  77. data/lib/puma/util.rb +23 -10
  78. data/lib/puma.rb +68 -5
  79. data/lib/rack/handler/puma.rb +119 -86
  80. data/tools/Dockerfile +16 -0
  81. data/tools/trickletest.rb +0 -1
  82. metadata +55 -33
  83. data/ext/puma_http11/io_buffer.c +0 -155
  84. data/lib/puma/accept_nonblock.rb +0 -23
  85. data/lib/puma/compat.rb +0 -14
  86. data/lib/puma/convenient.rb +0 -23
  87. data/lib/puma/daemon_ext.rb +0 -31
  88. data/lib/puma/delegation.rb +0 -11
  89. data/lib/puma/java_io_buffer.rb +0 -45
  90. data/lib/puma/rack/backports/uri/common_193.rb +0 -33
  91. data/lib/puma/tcp_logger.rb +0 -39
  92. data/tools/jungle/README.md +0 -13
  93. data/tools/jungle/init.d/README.md +0 -59
  94. data/tools/jungle/init.d/puma +0 -421
  95. data/tools/jungle/init.d/run-puma +0 -18
  96. data/tools/jungle/upstart/README.md +0 -61
  97. data/tools/jungle/upstart/puma-manager.conf +0 -31
  98. data/tools/jungle/upstart/puma.conf +0 -69
data/lib/puma/single.rb CHANGED
@@ -1,91 +1,47 @@
1
- require 'puma/runner'
2
- require 'puma/detect'
3
- require 'puma/plugin'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'runner'
4
+ require_relative 'detect'
5
+ require_relative 'plugin'
4
6
 
5
7
  module Puma
8
+ # This class is instantiated by the `Puma::Launcher` and used
9
+ # to boot and serve a Ruby application when no puma "workers" are needed
10
+ # i.e. only using "threaded" mode. For example `$ puma -t 1:5`
11
+ #
12
+ # At the core of this class is running an instance of `Puma::Server` which
13
+ # gets created via the `start_server` method from the `Puma::Runner` class
14
+ # that this inherits from.
6
15
  class Single < Runner
16
+ # @!attribute [r] stats
7
17
  def stats
8
- b = @server.backlog || 0
9
- r = @server.running || 0
10
- %Q!{ "backlog": #{b}, "running": #{r} }!
18
+ {
19
+ started_at: utc_iso8601(@started_at)
20
+ }.merge(@server.stats).merge(super)
11
21
  end
12
22
 
13
23
  def restart
14
- @server.begin_restart
24
+ @server&.begin_restart
15
25
  end
16
26
 
17
27
  def stop
18
- @server.stop false
28
+ @server&.stop false
19
29
  end
20
30
 
21
31
  def halt
22
- @server.halt
32
+ @server&.halt
23
33
  end
24
34
 
25
35
  def stop_blocked
26
36
  log "- Gracefully stopping, waiting for requests to finish"
27
- @control.stop(true) if @control
28
- @server.stop(true)
29
- end
30
-
31
- def jruby_daemon?
32
- daemon? and Puma.jruby?
33
- end
34
-
35
- def jruby_daemon_start
36
- require 'puma/jruby_restart'
37
- JRubyRestart.daemon_start(@restart_dir, @launcher.restart_args)
37
+ @control&.stop true
38
+ @server&.stop true
38
39
  end
39
40
 
40
41
  def run
41
- already_daemon = false
42
-
43
- if jruby_daemon?
44
- require 'puma/jruby_restart'
45
-
46
- if JRubyRestart.daemon?
47
- # load and bind before redirecting IO so errors show up on stdout/stderr
48
- load_and_bind
49
- redirect_io
50
- end
51
-
52
- already_daemon = JRubyRestart.daemon_init
53
- end
54
-
55
42
  output_header "single"
56
43
 
57
- if jruby_daemon?
58
- if already_daemon
59
- JRubyRestart.perm_daemonize
60
- else
61
- pid = nil
62
-
63
- Signal.trap "SIGUSR2" do
64
- log "* Started new process #{pid} as daemon..."
65
-
66
- # Must use exit! so we don't unwind and run the ensures
67
- # that will be run by the new child (such as deleting the
68
- # pidfile)
69
- exit!(true)
70
- end
71
-
72
- Signal.trap "SIGCHLD" do
73
- log "! Error starting new process as daemon, exiting"
74
- exit 1
75
- end
76
-
77
- jruby_daemon_start
78
- sleep
79
- end
80
- else
81
- if daemon?
82
- log "* Daemonizing..."
83
- Process.daemon(true)
84
- redirect_io
85
- end
86
-
87
- load_and_bind
88
- end
44
+ load_and_bind
89
45
 
90
46
  Plugins.fire_background
91
47
 
@@ -94,16 +50,17 @@ module Puma
94
50
  start_control
95
51
 
96
52
  @server = server = start_server
53
+ server_thread = server.run
97
54
 
98
- unless daemon?
99
- log "Use Ctrl-C to stop"
100
- redirect_io
101
- end
55
+ log "Use Ctrl-C to stop"
56
+ redirect_io
57
+
58
+ @events.fire_on_booted!
102
59
 
103
- @launcher.events.fire_on_booted!
60
+ debug_loaded_extensions("Loaded Extensions:") if @log_writer.debug?
104
61
 
105
62
  begin
106
- server.run.join
63
+ server_thread.join
107
64
  rescue Interrupt
108
65
  # Swallow it
109
66
  end
@@ -1,27 +1,66 @@
1
- require 'yaml'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Puma
4
+
5
+ # Puma::Launcher uses StateFile to write a yaml file for use with Puma::ControlCLI.
6
+ #
7
+ # In previous versions of Puma, YAML was used to read/write the state file.
8
+ # Since Puma is similar to Bundler/RubyGems in that it may load before one's app
9
+ # does, minimizing the dependencies that may be shared with the app is desired.
10
+ #
11
+ # At present, it only works with numeric and string values. It is still a valid
12
+ # yaml file, and the CI tests parse it with Psych.
13
+ #
4
14
  class StateFile
15
+
16
+ ALLOWED_FIELDS = %w!control_url control_auth_token pid running_from!
17
+
5
18
  def initialize
6
19
  @options = {}
7
20
  end
8
21
 
9
- def save(path)
10
- File.write path, YAML.dump(@options)
22
+ def save(path, permission = nil)
23
+ contents = +"---\n"
24
+ @options.each do |k,v|
25
+ next unless ALLOWED_FIELDS.include? k
26
+ case v
27
+ when Numeric
28
+ contents << "#{k}: #{v}\n"
29
+ when String
30
+ next if v.strip.empty?
31
+ contents << (k == 'running_from' || v.to_s.include?(' ') ?
32
+ "#{k}: \"#{v}\"\n" : "#{k}: #{v}\n")
33
+ end
34
+ end
35
+ if permission
36
+ File.write path, contents, mode: 'wb:UTF-8'
37
+ else
38
+ File.write path, contents, mode: 'wb:UTF-8', perm: permission
39
+ end
11
40
  end
12
41
 
13
42
  def load(path)
14
- @options = YAML.load File.read(path)
43
+ File.read(path).lines.each do |line|
44
+ next if line.start_with? '#'
45
+ k,v = line.split ':', 2
46
+ next unless v && ALLOWED_FIELDS.include?(k)
47
+ v = v.strip
48
+ @options[k] =
49
+ case v
50
+ when '' then nil
51
+ when /\A\d+\z/ then v.to_i
52
+ when /\A\d+\.\d+\z/ then v.to_f
53
+ else v.gsub(/\A"|"\z/, '')
54
+ end
55
+ end
15
56
  end
16
57
 
17
- FIELDS = %w!control_url control_auth_token pid!
18
-
19
- FIELDS.each do |f|
20
- define_method f do
58
+ ALLOWED_FIELDS.each do |f|
59
+ define_method f.to_sym do
21
60
  @options[f]
22
61
  end
23
62
 
24
- define_method "#{f}=" do |v|
63
+ define_method :"#{f}=" do |v|
25
64
  @options[f] = v
26
65
  end
27
66
  end