puma 3.9.0 → 3.12.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.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +5 -5
 - data/History.md +98 -0
 - data/README.md +140 -230
 - data/docs/architecture.md +36 -0
 - data/{DEPLOYMENT.md → docs/deployment.md} +0 -0
 - data/docs/images/puma-connection-flow-no-reactor.png +0 -0
 - data/docs/images/puma-connection-flow.png +0 -0
 - data/docs/images/puma-general-arch.png +0 -0
 - data/docs/plugins.md +28 -0
 - data/docs/restart.md +39 -0
 - data/docs/signals.md +56 -3
 - data/docs/systemd.md +112 -37
 - data/ext/puma_http11/http11_parser.c +84 -84
 - data/ext/puma_http11/http11_parser.rl +9 -9
 - data/ext/puma_http11/mini_ssl.c +18 -4
 - data/ext/puma_http11/org/jruby/puma/Http11Parser.java +13 -16
 - data/ext/puma_http11/org/jruby/puma/MiniSSL.java +6 -0
 - data/lib/puma.rb +8 -0
 - data/lib/puma/app/status.rb +8 -0
 - data/lib/puma/binder.rb +12 -8
 - data/lib/puma/cli.rb +20 -7
 - data/lib/puma/client.rb +28 -0
 - data/lib/puma/cluster.rb +26 -7
 - data/lib/puma/configuration.rb +19 -14
 - data/lib/puma/const.rb +7 -2
 - data/lib/puma/control_cli.rb +5 -5
 - data/lib/puma/dsl.rb +34 -7
 - data/lib/puma/jruby_restart.rb +0 -1
 - data/lib/puma/launcher.rb +36 -19
 - data/lib/puma/minissl.rb +49 -27
 - data/lib/puma/plugin/tmp_restart.rb +0 -1
 - data/lib/puma/reactor.rb +135 -0
 - data/lib/puma/runner.rb +12 -1
 - data/lib/puma/server.rb +84 -25
 - data/lib/puma/single.rb +12 -3
 - data/lib/puma/thread_pool.rb +47 -8
 - data/lib/rack/handler/puma.rb +4 -1
 - data/tools/jungle/README.md +12 -2
 - data/tools/jungle/init.d/README.md +2 -0
 - data/tools/jungle/init.d/puma +2 -2
 - data/tools/jungle/init.d/run-puma +1 -1
 - data/tools/jungle/rc.d/README.md +74 -0
 - data/tools/jungle/rc.d/puma +61 -0
 - data/tools/jungle/rc.d/puma.conf +10 -0
 - data/tools/trickletest.rb +1 -1
 - metadata +21 -94
 - data/.github/issue_template.md +0 -20
 - data/Gemfile +0 -12
 - data/Manifest.txt +0 -78
 - data/Rakefile +0 -158
 - data/Release.md +0 -9
 - data/gemfiles/2.1-Gemfile +0 -12
 - data/puma.gemspec +0 -52
 
    
        data/lib/puma/cluster.rb
    CHANGED
    
    | 
         @@ -5,6 +5,17 @@ require 'puma/plugin' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require 'time'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            module Puma
         
     | 
| 
      
 8 
     | 
    
         
            +
              # This class is instantiated by the `Puma::Launcher` and used
         
     | 
| 
      
 9 
     | 
    
         
            +
              # to boot and serve a Ruby application when puma "workers" are needed
         
     | 
| 
      
 10 
     | 
    
         
            +
              # i.e. when using multi-processes. For example `$ puma -w 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.
         
     | 
| 
      
 15 
     | 
    
         
            +
              #
         
     | 
| 
      
 16 
     | 
    
         
            +
              # An instance of this class will spawn the number of processes passed in
         
     | 
| 
      
 17 
     | 
    
         
            +
              # via the `spawn_workers` method call. Each worker will have it's own
         
     | 
| 
      
 18 
     | 
    
         
            +
              # instance of a `Puma::Server`.
         
     | 
| 
       8 
19 
     | 
    
         
             
              class Cluster < Runner
         
     | 
| 
       9 
20 
     | 
    
         
             
                WORKER_CHECK_INTERVAL = 5
         
     | 
| 
       10 
21 
     | 
    
         | 
| 
         @@ -24,7 +35,7 @@ module Puma 
     | 
|
| 
       24 
35 
     | 
    
         
             
                  @workers.each { |x| x.term }
         
     | 
| 
       25 
36 
     | 
    
         | 
| 
       26 
37 
     | 
    
         
             
                  begin
         
     | 
| 
       27 
     | 
    
         
            -
                    Process. 
     | 
| 
      
 38 
     | 
    
         
            +
                    @workers.each { |w| Process.waitpid(w.pid) }
         
     | 
| 
       28 
39 
     | 
    
         
             
                  rescue Interrupt
         
     | 
| 
       29 
40 
     | 
    
         
             
                    log "! Cancelled waiting for workers"
         
     | 
| 
       30 
41 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -224,12 +235,13 @@ module Puma 
     | 
|
| 
       224 
235 
     | 
    
         
             
                  begin
         
     | 
| 
       225 
236 
     | 
    
         
             
                    @wakeup.write "!" unless @wakeup.closed?
         
     | 
| 
       226 
237 
     | 
    
         
             
                  rescue SystemCallError, IOError
         
     | 
| 
      
 238 
     | 
    
         
            +
                    Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         
     | 
| 
       227 
239 
     | 
    
         
             
                  end
         
     | 
| 
       228 
240 
     | 
    
         
             
                end
         
     | 
| 
       229 
241 
     | 
    
         | 
| 
       230 
242 
     | 
    
         
             
                def worker(index, master)
         
     | 
| 
       231 
     | 
    
         
            -
                  title 
     | 
| 
       232 
     | 
    
         
            -
                  title  
     | 
| 
      
 243 
     | 
    
         
            +
                  title  = "puma: cluster worker #{index}: #{master}"
         
     | 
| 
      
 244 
     | 
    
         
            +
                  title += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
         
     | 
| 
       233 
245 
     | 
    
         
             
                  $0 = title
         
     | 
| 
       234 
246 
     | 
    
         | 
| 
       235 
247 
     | 
    
         
             
                  Signal.trap "SIGINT", "IGNORE"
         
     | 
| 
         @@ -267,6 +279,7 @@ module Puma 
     | 
|
| 
       267 
279 
     | 
    
         
             
                  begin
         
     | 
| 
       268 
280 
     | 
    
         
             
                    @worker_write << "b#{Process.pid}\n"
         
     | 
| 
       269 
281 
     | 
    
         
             
                  rescue SystemCallError, IOError
         
     | 
| 
      
 282 
     | 
    
         
            +
                    Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         
     | 
| 
       270 
283 
     | 
    
         
             
                    STDERR.puts "Master seems to have exited, exiting."
         
     | 
| 
       271 
284 
     | 
    
         
             
                    return
         
     | 
| 
       272 
285 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -277,11 +290,14 @@ module Puma 
     | 
|
| 
       277 
290 
     | 
    
         
             
                    while true
         
     | 
| 
       278 
291 
     | 
    
         
             
                      sleep WORKER_CHECK_INTERVAL
         
     | 
| 
       279 
292 
     | 
    
         
             
                      begin
         
     | 
| 
       280 
     | 
    
         
            -
                        b = server.backlog
         
     | 
| 
       281 
     | 
    
         
            -
                        r = server.running
         
     | 
| 
       282 
     | 
    
         
            -
                         
     | 
| 
      
 293 
     | 
    
         
            +
                        b = server.backlog || 0
         
     | 
| 
      
 294 
     | 
    
         
            +
                        r = server.running || 0
         
     | 
| 
      
 295 
     | 
    
         
            +
                        t = server.pool_capacity || 0
         
     | 
| 
      
 296 
     | 
    
         
            +
                        m = server.max_threads || 0
         
     | 
| 
      
 297 
     | 
    
         
            +
                        payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m} }\n!
         
     | 
| 
       283 
298 
     | 
    
         
             
                        io << payload
         
     | 
| 
       284 
299 
     | 
    
         
             
                      rescue IOError
         
     | 
| 
      
 300 
     | 
    
         
            +
                        Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         
     | 
| 
       285 
301 
     | 
    
         
             
                        break
         
     | 
| 
       286 
302 
     | 
    
         
             
                      end
         
     | 
| 
       287 
303 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -337,7 +353,7 @@ module Puma 
     | 
|
| 
       337 
353 
     | 
    
         
             
                def stats
         
     | 
| 
       338 
354 
     | 
    
         
             
                  old_worker_count = @workers.count { |w| w.phase != @phase }
         
     | 
| 
       339 
355 
     | 
    
         
             
                  booted_worker_count = @workers.count { |w| w.booted? }
         
     | 
| 
       340 
     | 
    
         
            -
                  worker_status = '[' + @workers.map{ |w| %Q!{ "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']'
         
     | 
| 
      
 356 
     | 
    
         
            +
                  worker_status = '[' + @workers.map { |w| %Q!{ "pid": #{w.pid}, "index": #{w.index}, "phase": #{w.phase}, "booted": #{w.booted?}, "last_checkin": "#{w.last_checkin.utc.iso8601}", "last_status": #{w.last_status} }!}.join(",") + ']'
         
     | 
| 
       341 
357 
     | 
    
         
             
                  %Q!{ "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count}, "worker_status": #{worker_status} }!
         
     | 
| 
       342 
358 
     | 
    
         
             
                end
         
     | 
| 
       343 
359 
     | 
    
         | 
| 
         @@ -372,7 +388,10 @@ module Puma 
     | 
|
| 
       372 
388 
     | 
    
         
             
                      log "Early termination of worker"
         
     | 
| 
       373 
389 
     | 
    
         
             
                      exit! 0
         
     | 
| 
       374 
390 
     | 
    
         
             
                    else
         
     | 
| 
      
 391 
     | 
    
         
            +
                      stop_workers
         
     | 
| 
       375 
392 
     | 
    
         
             
                      stop
         
     | 
| 
      
 393 
     | 
    
         
            +
             
     | 
| 
      
 394 
     | 
    
         
            +
                      raise SignalException, "SIGTERM"
         
     | 
| 
       376 
395 
     | 
    
         
             
                    end
         
     | 
| 
       377 
396 
     | 
    
         
             
                  end
         
     | 
| 
       378 
397 
     | 
    
         
             
                end
         
     | 
    
        data/lib/puma/configuration.rb
    CHANGED
    
    | 
         @@ -180,30 +180,31 @@ module Puma 
     | 
|
| 
       180 
180 
     | 
    
         
             
                    :worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
         
     | 
| 
       181 
181 
     | 
    
         
             
                    :remote_address => :socket,
         
     | 
| 
       182 
182 
     | 
    
         
             
                    :tag => method(:infer_tag),
         
     | 
| 
       183 
     | 
    
         
            -
                    :environment => ->{ ENV['RACK_ENV'] || "development" },
         
     | 
| 
      
 183 
     | 
    
         
            +
                    :environment => -> { ENV['RACK_ENV'] || "development" },
         
     | 
| 
       184 
184 
     | 
    
         
             
                    :rackup => DefaultRackup,
         
     | 
| 
       185 
185 
     | 
    
         
             
                    :logger => STDOUT,
         
     | 
| 
       186 
     | 
    
         
            -
                    :persistent_timeout => Const::PERSISTENT_TIMEOUT
         
     | 
| 
      
 186 
     | 
    
         
            +
                    :persistent_timeout => Const::PERSISTENT_TIMEOUT,
         
     | 
| 
      
 187 
     | 
    
         
            +
                    :first_data_timeout => Const::FIRST_DATA_TIMEOUT
         
     | 
| 
       187 
188 
     | 
    
         
             
                  }
         
     | 
| 
       188 
189 
     | 
    
         
             
                end
         
     | 
| 
       189 
190 
     | 
    
         | 
| 
       190 
191 
     | 
    
         
             
                def load
         
     | 
| 
      
 192 
     | 
    
         
            +
                  config_files.each { |config_file| @file_dsl._load_from(config_file) }
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                  @options
         
     | 
| 
      
 195 
     | 
    
         
            +
                end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                def config_files
         
     | 
| 
       191 
198 
     | 
    
         
             
                  files = @options.all_of(:config_files)
         
     | 
| 
       192 
199 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
                  if files 
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
                      File.exist?(f)
         
     | 
| 
       196 
     | 
    
         
            -
                    }
         
     | 
| 
      
 200 
     | 
    
         
            +
                  return [] if files == ['-']
         
     | 
| 
      
 201 
     | 
    
         
            +
                  return files if files.any?
         
     | 
| 
       197 
202 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                    files = []
         
     | 
| 
      
 203 
     | 
    
         
            +
                  first_default_file = %W(config/puma/#{environment_str}.rb config/puma.rb).find do |f|
         
     | 
| 
      
 204 
     | 
    
         
            +
                    File.exist?(f)
         
     | 
| 
       201 
205 
     | 
    
         
             
                  end
         
     | 
| 
       202 
206 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
                   
     | 
| 
       204 
     | 
    
         
            -
                    @file_dsl._load_from(f)
         
     | 
| 
       205 
     | 
    
         
            -
                  end
         
     | 
| 
       206 
     | 
    
         
            -
                  @options
         
     | 
| 
      
 207 
     | 
    
         
            +
                  [first_default_file]
         
     | 
| 
       207 
208 
     | 
    
         
             
                end
         
     | 
| 
       208 
209 
     | 
    
         | 
| 
       209 
210 
     | 
    
         
             
                # Call once all configuration (included from rackup files)
         
     | 
| 
         @@ -263,6 +264,10 @@ module Puma 
     | 
|
| 
       263 
264 
     | 
    
         
             
                  @options[:environment]
         
     | 
| 
       264 
265 
     | 
    
         
             
                end
         
     | 
| 
       265 
266 
     | 
    
         | 
| 
      
 267 
     | 
    
         
            +
                def environment_str
         
     | 
| 
      
 268 
     | 
    
         
            +
                  environment.respond_to?(:call) ? environment.call : environment
         
     | 
| 
      
 269 
     | 
    
         
            +
                end
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
       266 
271 
     | 
    
         
             
                def load_plugin(name)
         
     | 
| 
       267 
272 
     | 
    
         
             
                  @plugins.create name
         
     | 
| 
       268 
273 
     | 
    
         
             
                end
         
     | 
| 
         @@ -340,7 +345,7 @@ module Puma 
     | 
|
| 
       340 
345 
     | 
    
         
             
                  end
         
     | 
| 
       341 
346 
     | 
    
         | 
| 
       342 
347 
     | 
    
         
             
                  if bytes
         
     | 
| 
       343 
     | 
    
         
            -
                    token = ""
         
     | 
| 
      
 348 
     | 
    
         
            +
                    token = "".dup
         
     | 
| 
       344 
349 
     | 
    
         
             
                    bytes.each_byte { |b| token << b.to_s(16) }
         
     | 
| 
       345 
350 
     | 
    
         
             
                  else
         
     | 
| 
       346 
351 
     | 
    
         
             
                    token = (0..count).to_a.map { rand(255).to_s(16) }.join
         
     | 
    
        data/lib/puma/const.rb
    CHANGED
    
    | 
         @@ -53,6 +53,8 @@ module Puma 
     | 
|
| 
       53 
53 
     | 
    
         
             
                415 => 'Unsupported Media Type',
         
     | 
| 
       54 
54 
     | 
    
         
             
                416 => 'Range Not Satisfiable',
         
     | 
| 
       55 
55 
     | 
    
         
             
                417 => 'Expectation Failed',
         
     | 
| 
      
 56 
     | 
    
         
            +
                418 => 'I\'m A Teapot',
         
     | 
| 
      
 57 
     | 
    
         
            +
                421 => 'Misdirected Request',
         
     | 
| 
       56 
58 
     | 
    
         
             
                422 => 'Unprocessable Entity',
         
     | 
| 
       57 
59 
     | 
    
         
             
                423 => 'Locked',
         
     | 
| 
       58 
60 
     | 
    
         
             
                424 => 'Failed Dependency',
         
     | 
| 
         @@ -60,6 +62,7 @@ module Puma 
     | 
|
| 
       60 
62 
     | 
    
         
             
                428 => 'Precondition Required',
         
     | 
| 
       61 
63 
     | 
    
         
             
                429 => 'Too Many Requests',
         
     | 
| 
       62 
64 
     | 
    
         
             
                431 => 'Request Header Fields Too Large',
         
     | 
| 
      
 65 
     | 
    
         
            +
                451 => 'Unavailable For Legal Reasons',
         
     | 
| 
       63 
66 
     | 
    
         
             
                500 => 'Internal Server Error',
         
     | 
| 
       64 
67 
     | 
    
         
             
                501 => 'Not Implemented',
         
     | 
| 
       65 
68 
     | 
    
         
             
                502 => 'Bad Gateway',
         
     | 
| 
         @@ -95,8 +98,8 @@ module Puma 
     | 
|
| 
       95 
98 
     | 
    
         
             
              # too taxing on performance.
         
     | 
| 
       96 
99 
     | 
    
         
             
              module Const
         
     | 
| 
       97 
100 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
                PUMA_VERSION = VERSION = "3. 
     | 
| 
       99 
     | 
    
         
            -
                CODE_NAME = " 
     | 
| 
      
 101 
     | 
    
         
            +
                PUMA_VERSION = VERSION = "3.12.0".freeze
         
     | 
| 
      
 102 
     | 
    
         
            +
                CODE_NAME = "Llamas in Pajamas".freeze
         
     | 
| 
       100 
103 
     | 
    
         
             
                PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
         
     | 
| 
       101 
104 
     | 
    
         | 
| 
       102 
105 
     | 
    
         
             
                FAST_TRACK_KA_TIMEOUT = 0.2
         
     | 
| 
         @@ -220,5 +223,7 @@ module Puma 
     | 
|
| 
       220 
223 
     | 
    
         
             
                HIJACK_P = "rack.hijack?".freeze
         
     | 
| 
       221 
224 
     | 
    
         
             
                HIJACK = "rack.hijack".freeze
         
     | 
| 
       222 
225 
     | 
    
         
             
                HIJACK_IO = "rack.hijack_io".freeze
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                EARLY_HINTS = "rack.early_hints".freeze
         
     | 
| 
       223 
228 
     | 
    
         
             
              end
         
     | 
| 
       224 
229 
     | 
    
         
             
            end
         
     | 
    
        data/lib/puma/control_cli.rb
    CHANGED
    
    | 
         @@ -9,7 +9,7 @@ require 'socket' 
     | 
|
| 
       9 
9 
     | 
    
         
             
            module Puma
         
     | 
| 
       10 
10 
     | 
    
         
             
              class ControlCLI
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                COMMANDS = %w{halt restart phased-restart start stats status stop reload-worker-directory}
         
     | 
| 
      
 12 
     | 
    
         
            +
                COMMANDS = %w{halt restart phased-restart start stats status stop reload-worker-directory gc gc-stats}
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                def initialize(argv, stdout=STDOUT, stderr=STDERR)
         
     | 
| 
       15 
15 
     | 
    
         
             
                  @state = nil
         
     | 
| 
         @@ -69,6 +69,7 @@ module Puma 
     | 
|
| 
       69 
69 
     | 
    
         
             
                  end
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
71 
     | 
    
         
             
                  opts.order!(argv) { |a| opts.terminate a }
         
     | 
| 
      
 72 
     | 
    
         
            +
                  opts.parse!
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
       73 
74 
     | 
    
         
             
                  @command = argv.shift
         
     | 
| 
       74 
75 
     | 
    
         | 
| 
         @@ -169,7 +170,7 @@ module Puma 
     | 
|
| 
       169 
170 
     | 
    
         
             
                    end
         
     | 
| 
       170 
171 
     | 
    
         | 
| 
       171 
172 
     | 
    
         
             
                    message "Command #{@command} sent success"
         
     | 
| 
       172 
     | 
    
         
            -
                    message response.last if @command == "stats"
         
     | 
| 
      
 173 
     | 
    
         
            +
                    message response.last if @command == "stats" || @command == "gc-stats"
         
     | 
| 
       173 
174 
     | 
    
         
             
                  end
         
     | 
| 
       174 
175 
     | 
    
         | 
| 
       175 
176 
     | 
    
         
             
                  @server.close
         
     | 
| 
         @@ -204,7 +205,6 @@ module Puma 
     | 
|
| 
       204 
205 
     | 
    
         
             
                      Process.kill "SIGUSR1", @pid
         
     | 
| 
       205 
206 
     | 
    
         | 
| 
       206 
207 
     | 
    
         
             
                    else
         
     | 
| 
       207 
     | 
    
         
            -
                      message "Puma is started"
         
     | 
| 
       208 
208 
     | 
    
         
             
                      return
         
     | 
| 
       209 
209 
     | 
    
         
             
                    end
         
     | 
| 
       210 
210 
     | 
    
         | 
| 
         @@ -220,7 +220,7 @@ module Puma 
     | 
|
| 
       220 
220 
     | 
    
         
             
                end
         
     | 
| 
       221 
221 
     | 
    
         | 
| 
       222 
222 
     | 
    
         
             
                def run
         
     | 
| 
       223 
     | 
    
         
            -
                  start if @command == "start"
         
     | 
| 
      
 223 
     | 
    
         
            +
                  return start if @command == "start"
         
     | 
| 
       224 
224 
     | 
    
         | 
| 
       225 
225 
     | 
    
         
             
                  prepare_configuration
         
     | 
| 
       226 
226 
     | 
    
         | 
| 
         @@ -245,7 +245,7 @@ module Puma 
     | 
|
| 
       245 
245 
     | 
    
         
             
                  run_args += ["-S", @state]  if @state
         
     | 
| 
       246 
246 
     | 
    
         
             
                  run_args += ["-q"] if @quiet
         
     | 
| 
       247 
247 
     | 
    
         
             
                  run_args += ["--pidfile", @pidfile] if @pidfile
         
     | 
| 
       248 
     | 
    
         
            -
                  run_args += ["--control", @control_url] if @control_url
         
     | 
| 
      
 248 
     | 
    
         
            +
                  run_args += ["--control-url", @control_url] if @control_url
         
     | 
| 
       249 
249 
     | 
    
         
             
                  run_args += ["--control-token", @control_auth_token] if @control_auth_token
         
     | 
| 
       250 
250 
     | 
    
         
             
                  run_args += ["-C", @config_file] if @config_file
         
     | 
| 
       251 
251 
     | 
    
         | 
    
        data/lib/puma/dsl.rb
    CHANGED
    
    | 
         @@ -110,14 +110,31 @@ module Puma 
     | 
|
| 
       110 
110 
     | 
    
         
             
                  @options[:config_files] << file
         
     | 
| 
       111 
111 
     | 
    
         
             
                end
         
     | 
| 
       112 
112 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                #  
     | 
| 
       114 
     | 
    
         
            -
                # protocols.
         
     | 
| 
      
 113 
     | 
    
         
            +
                # Adds a binding for the server to +url+. tcp://, unix://, and ssl:// are the only accepted
         
     | 
| 
      
 114 
     | 
    
         
            +
                # protocols. Use query parameters within the url to specify options.
         
     | 
| 
       115 
115 
     | 
    
         
             
                #
         
     | 
| 
      
 116 
     | 
    
         
            +
                # @note multiple urls can be bound to, calling `bind` does not overwrite previous bindings.
         
     | 
| 
      
 117 
     | 
    
         
            +
                #
         
     | 
| 
      
 118 
     | 
    
         
            +
                # @example Explicitly the socket backlog depth (default is 1024)
         
     | 
| 
      
 119 
     | 
    
         
            +
                #   bind('unix:///var/run/puma.sock?backlog=2048')
         
     | 
| 
      
 120 
     | 
    
         
            +
                #
         
     | 
| 
      
 121 
     | 
    
         
            +
                # @example Set up ssl cert
         
     | 
| 
      
 122 
     | 
    
         
            +
                #   bind('ssl://127.0.0.1:9292?key=key.key&cert=cert.pem')
         
     | 
| 
      
 123 
     | 
    
         
            +
                #
         
     | 
| 
      
 124 
     | 
    
         
            +
                # @example Prefer low-latency over higher throughput (via `Socket::TCP_NODELAY`)
         
     | 
| 
      
 125 
     | 
    
         
            +
                #   bind('tcp://0.0.0.0:9292?low_latency=true')
         
     | 
| 
      
 126 
     | 
    
         
            +
                #
         
     | 
| 
      
 127 
     | 
    
         
            +
                # @example Set socket permissions
         
     | 
| 
      
 128 
     | 
    
         
            +
                #   bind('unix:///var/run/puma.sock?umask=0111')
         
     | 
| 
       116 
129 
     | 
    
         
             
                def bind(url)
         
     | 
| 
       117 
130 
     | 
    
         
             
                  @options[:binds] ||= []
         
     | 
| 
       118 
131 
     | 
    
         
             
                  @options[:binds] << url
         
     | 
| 
       119 
132 
     | 
    
         
             
                end
         
     | 
| 
       120 
133 
     | 
    
         | 
| 
      
 134 
     | 
    
         
            +
                def clear_binds!
         
     | 
| 
      
 135 
     | 
    
         
            +
                  @options[:binds] = []
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
       121 
138 
     | 
    
         
             
                # Define the TCP port to bind to. Use +bind+ for more advanced options.
         
     | 
| 
       122 
139 
     | 
    
         
             
                #
         
     | 
| 
       123 
140 
     | 
    
         
             
                def port(port, host=nil)
         
     | 
| 
         @@ -129,7 +146,13 @@ module Puma 
     | 
|
| 
       129 
146 
     | 
    
         
             
                # them
         
     | 
| 
       130 
147 
     | 
    
         
             
                #
         
     | 
| 
       131 
148 
     | 
    
         
             
                def persistent_timeout(seconds)
         
     | 
| 
       132 
     | 
    
         
            -
                  @options[:persistent_timeout] = seconds
         
     | 
| 
      
 149 
     | 
    
         
            +
                  @options[:persistent_timeout] = Integer(seconds)
         
     | 
| 
      
 150 
     | 
    
         
            +
                end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                # Define how long the tcp socket stays open, if no data has been received
         
     | 
| 
      
 153 
     | 
    
         
            +
                #
         
     | 
| 
      
 154 
     | 
    
         
            +
                def first_data_timeout(seconds)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  @options[:first_data_timeout] = Integer(seconds)
         
     | 
| 
       133 
156 
     | 
    
         
             
                end
         
     | 
| 
       134 
157 
     | 
    
         | 
| 
       135 
158 
     | 
    
         
             
                # Work around leaky apps that leave garbage in Thread locals
         
     | 
| 
         @@ -146,7 +169,7 @@ module Puma 
     | 
|
| 
       146 
169 
     | 
    
         
             
                end
         
     | 
| 
       147 
170 
     | 
    
         | 
| 
       148 
171 
     | 
    
         
             
                # When shutting down, drain the accept socket of pending
         
     | 
| 
       149 
     | 
    
         
            -
                # connections and  
     | 
| 
      
 172 
     | 
    
         
            +
                # connections and process them. This loops over the accept
         
     | 
| 
       150 
173 
     | 
    
         
             
                # socket until there are no more read events and then stops
         
     | 
| 
       151 
174 
     | 
    
         
             
                # looking and waits for the requests to finish.
         
     | 
| 
       152 
175 
     | 
    
         
             
                def drain_on_shutdown(which=true)
         
     | 
| 
         @@ -231,6 +254,10 @@ module Puma 
     | 
|
| 
       231 
254 
     | 
    
         
             
                  @options[:mode] = :tcp
         
     | 
| 
       232 
255 
     | 
    
         
             
                end
         
     | 
| 
       233 
256 
     | 
    
         | 
| 
      
 257 
     | 
    
         
            +
                def early_hints(answer=true)
         
     | 
| 
      
 258 
     | 
    
         
            +
                  @options[:early_hints] = answer
         
     | 
| 
      
 259 
     | 
    
         
            +
                end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
       234 
261 
     | 
    
         
             
                # Redirect STDOUT and STDERR to files specified.
         
     | 
| 
       235 
262 
     | 
    
         
             
                def stdout_redirect(stdout=nil, stderr=nil, append=false)
         
     | 
| 
       236 
263 
     | 
    
         
             
                  @options[:redirect_stdout] = stdout
         
     | 
| 
         @@ -397,17 +424,17 @@ module Puma 
     | 
|
| 
       397 
424 
     | 
    
         
             
                # that have not checked in within the given +timeout+.
         
     | 
| 
       398 
425 
     | 
    
         
             
                # This mitigates hung processes. Default value is 60 seconds.
         
     | 
| 
       399 
426 
     | 
    
         
             
                def worker_timeout(timeout)
         
     | 
| 
       400 
     | 
    
         
            -
                  @options[:worker_timeout] = timeout
         
     | 
| 
      
 427 
     | 
    
         
            +
                  @options[:worker_timeout] = Integer(timeout)
         
     | 
| 
       401 
428 
     | 
    
         
             
                end
         
     | 
| 
       402 
429 
     | 
    
         | 
| 
       403 
430 
     | 
    
         
             
                # *Cluster mode only* Set the timeout for workers to boot
         
     | 
| 
       404 
431 
     | 
    
         
             
                def worker_boot_timeout(timeout)
         
     | 
| 
       405 
     | 
    
         
            -
                  @options[:worker_boot_timeout] = timeout
         
     | 
| 
      
 432 
     | 
    
         
            +
                  @options[:worker_boot_timeout] = Integer(timeout)
         
     | 
| 
       406 
433 
     | 
    
         
             
                end
         
     | 
| 
       407 
434 
     | 
    
         | 
| 
       408 
435 
     | 
    
         
             
                # *Cluster mode only* Set the timeout for worker shutdown
         
     | 
| 
       409 
436 
     | 
    
         
             
                def worker_shutdown_timeout(timeout)
         
     | 
| 
       410 
     | 
    
         
            -
                  @options[:worker_shutdown_timeout] = timeout
         
     | 
| 
      
 437 
     | 
    
         
            +
                  @options[:worker_shutdown_timeout] = Integer(timeout)
         
     | 
| 
       411 
438 
     | 
    
         
             
                end
         
     | 
| 
       412 
439 
     | 
    
         | 
| 
       413 
440 
     | 
    
         
             
                # When set to true (the default), workers accept all requests
         
     | 
    
        data/lib/puma/jruby_restart.rb
    CHANGED
    
    
    
        data/lib/puma/launcher.rb
    CHANGED
    
    | 
         @@ -40,7 +40,7 @@ module Puma 
     | 
|
| 
       40 
40 
     | 
    
         
             
                #       [200, {}, ["hello world"]]
         
     | 
| 
       41 
41 
     | 
    
         
             
                #     end
         
     | 
| 
       42 
42 
     | 
    
         
             
                #   end
         
     | 
| 
       43 
     | 
    
         
            -
                #   Puma::Launcher.new(conf,  
     | 
| 
      
 43 
     | 
    
         
            +
                #   Puma::Launcher.new(conf, events: Puma::Events.stdio).run
         
     | 
| 
       44 
44 
     | 
    
         
             
                def initialize(conf, launcher_args={})
         
     | 
| 
       45 
45 
     | 
    
         
             
                  @runner        = nil
         
     | 
| 
       46 
46 
     | 
    
         
             
                  @events        = launcher_args[:events] || Events::DEFAULT
         
     | 
| 
         @@ -86,6 +86,7 @@ module Puma 
     | 
|
| 
       86 
86 
     | 
    
         
             
                  else
         
     | 
| 
       87 
87 
     | 
    
         
             
                    @runner = Single.new(self, @events)
         
     | 
| 
       88 
88 
     | 
    
         
             
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                  Puma.stats_object = @runner
         
     | 
| 
       89 
90 
     | 
    
         | 
| 
       90 
91 
     | 
    
         
             
                  @status = :run
         
     | 
| 
       91 
92 
     | 
    
         
             
                end
         
     | 
| 
         @@ -163,7 +164,16 @@ module Puma 
     | 
|
| 
       163 
164 
     | 
    
         | 
| 
       164 
165 
     | 
    
         
             
                # Run the server. This blocks until the server is stopped
         
     | 
| 
       165 
166 
     | 
    
         
             
                def run
         
     | 
| 
       166 
     | 
    
         
            -
                  previous_env = 
     | 
| 
      
 167 
     | 
    
         
            +
                  previous_env =
         
     | 
| 
      
 168 
     | 
    
         
            +
                    if defined?(Bundler)
         
     | 
| 
      
 169 
     | 
    
         
            +
                      env = Bundler::ORIGINAL_ENV.dup
         
     | 
| 
      
 170 
     | 
    
         
            +
                      # add -rbundler/setup so we load from Gemfile when restarting
         
     | 
| 
      
 171 
     | 
    
         
            +
                      bundle = "-rbundler/setup"
         
     | 
| 
      
 172 
     | 
    
         
            +
                      env["RUBYOPT"] = [env["RUBYOPT"], bundle].join(" ").lstrip unless env["RUBYOPT"].to_s.include?(bundle)
         
     | 
| 
      
 173 
     | 
    
         
            +
                      env
         
     | 
| 
      
 174 
     | 
    
         
            +
                    else
         
     | 
| 
      
 175 
     | 
    
         
            +
                      ENV.to_h
         
     | 
| 
      
 176 
     | 
    
         
            +
                    end
         
     | 
| 
       167 
177 
     | 
    
         | 
| 
       168 
178 
     | 
    
         
             
                  @config.clamp
         
     | 
| 
       169 
179 
     | 
    
         | 
| 
         @@ -225,8 +235,8 @@ module Puma 
     | 
|
| 
       225 
235 
     | 
    
         
             
                  else
         
     | 
| 
       226 
236 
     | 
    
         
             
                    redirects = {:close_others => true}
         
     | 
| 
       227 
237 
     | 
    
         
             
                    @binder.listeners.each_with_index do |(l, io), i|
         
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
      
 238 
     | 
    
         
            +
                      ENV["PUMA_INHERIT_#{i}"] = "#{io.to_i}:#{l}"
         
     | 
| 
      
 239 
     | 
    
         
            +
                      redirects[io.to_i] = io.to_i
         
     | 
| 
       230 
240 
     | 
    
         
             
                    end
         
     | 
| 
       231 
241 
     | 
    
         | 
| 
       232 
242 
     | 
    
         
             
                    argv = restart_args
         
     | 
| 
         @@ -289,8 +299,8 @@ module Puma 
     | 
|
| 
       289 
299 
     | 
    
         
             
                end
         
     | 
| 
       290 
300 
     | 
    
         | 
| 
       291 
301 
     | 
    
         
             
                def title
         
     | 
| 
       292 
     | 
    
         
            -
                  buffer 
     | 
| 
       293 
     | 
    
         
            -
                  buffer  
     | 
| 
      
 302 
     | 
    
         
            +
                  buffer  = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})"
         
     | 
| 
      
 303 
     | 
    
         
            +
                  buffer += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
         
     | 
| 
       294 
304 
     | 
    
         
             
                  buffer
         
     | 
| 
       295 
305 
     | 
    
         
             
                end
         
     | 
| 
       296 
306 
     | 
    
         | 
| 
         @@ -340,8 +350,6 @@ module Puma 
     | 
|
| 
       340 
350 
     | 
    
         | 
| 
       341 
351 
     | 
    
         
             
                  @restart_dir ||= Dir.pwd
         
     | 
| 
       342 
352 
     | 
    
         | 
| 
       343 
     | 
    
         
            -
                  require 'rubygems'
         
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
353 
     | 
    
         
             
                  # if $0 is a file in the current directory, then restart
         
     | 
| 
       346 
354 
     | 
    
         
             
                  # it the same, otherwise add -S on there because it was
         
     | 
| 
       347 
355 
     | 
    
         
             
                  # picked up in PATH.
         
     | 
| 
         @@ -352,9 +360,10 @@ module Puma 
     | 
|
| 
       352 
360 
     | 
    
         
             
                    arg0 = [Gem.ruby, "-S", $0]
         
     | 
| 
       353 
361 
     | 
    
         
             
                  end
         
     | 
| 
       354 
362 
     | 
    
         | 
| 
       355 
     | 
    
         
            -
                  # Detect and reinject -Ilib from the command line
         
     | 
| 
      
 363 
     | 
    
         
            +
                  # Detect and reinject -Ilib from the command line, used for testing without bundler
         
     | 
| 
      
 364 
     | 
    
         
            +
                  # cruby has an expanded path, jruby has just "lib"
         
     | 
| 
       356 
365 
     | 
    
         
             
                  lib = File.expand_path "lib"
         
     | 
| 
       357 
     | 
    
         
            -
                  arg0[1,0] = ["-I", lib] if  
     | 
| 
      
 366 
     | 
    
         
            +
                  arg0[1,0] = ["-I", lib] if [lib, "lib"].include?($LOAD_PATH[0])
         
     | 
| 
       358 
367 
     | 
    
         | 
| 
       359 
368 
     | 
    
         
             
                  if defined? Puma::WILD_ARGS
         
     | 
| 
       360 
369 
     | 
    
         
             
                    @restart_argv = arg0 + Puma::WILD_ARGS + @original_argv
         
     | 
| 
         @@ -384,12 +393,28 @@ module Puma 
     | 
|
| 
       384 
393 
     | 
    
         | 
| 
       385 
394 
     | 
    
         
             
                  begin
         
     | 
| 
       386 
395 
     | 
    
         
             
                    Signal.trap "SIGTERM" do
         
     | 
| 
       387 
     | 
    
         
            -
                       
     | 
| 
      
 396 
     | 
    
         
            +
                      graceful_stop
         
     | 
| 
      
 397 
     | 
    
         
            +
             
     | 
| 
      
 398 
     | 
    
         
            +
                      raise SignalException, "SIGTERM"
         
     | 
| 
       388 
399 
     | 
    
         
             
                    end
         
     | 
| 
       389 
400 
     | 
    
         
             
                  rescue Exception
         
     | 
| 
       390 
401 
     | 
    
         
             
                    log "*** SIGTERM not implemented, signal based gracefully stopping unavailable!"
         
     | 
| 
       391 
402 
     | 
    
         
             
                  end
         
     | 
| 
       392 
403 
     | 
    
         | 
| 
      
 404 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 405 
     | 
    
         
            +
                    Signal.trap "SIGINT" do
         
     | 
| 
      
 406 
     | 
    
         
            +
                      if Puma.jruby?
         
     | 
| 
      
 407 
     | 
    
         
            +
                        @status = :exit
         
     | 
| 
      
 408 
     | 
    
         
            +
                        graceful_stop
         
     | 
| 
      
 409 
     | 
    
         
            +
                        exit
         
     | 
| 
      
 410 
     | 
    
         
            +
                      end
         
     | 
| 
      
 411 
     | 
    
         
            +
             
     | 
| 
      
 412 
     | 
    
         
            +
                      stop
         
     | 
| 
      
 413 
     | 
    
         
            +
                    end
         
     | 
| 
      
 414 
     | 
    
         
            +
                  rescue Exception
         
     | 
| 
      
 415 
     | 
    
         
            +
                    log "*** SIGINT not implemented, signal based gracefully stopping unavailable!"
         
     | 
| 
      
 416 
     | 
    
         
            +
                  end
         
     | 
| 
      
 417 
     | 
    
         
            +
             
     | 
| 
       393 
418 
     | 
    
         
             
                  begin
         
     | 
| 
       394 
419 
     | 
    
         
             
                    Signal.trap "SIGHUP" do
         
     | 
| 
       395 
420 
     | 
    
         
             
                      if @runner.redirected_io?
         
     | 
| 
         @@ -401,14 +426,6 @@ module Puma 
     | 
|
| 
       401 
426 
     | 
    
         
             
                  rescue Exception
         
     | 
| 
       402 
427 
     | 
    
         
             
                    log "*** SIGHUP not implemented, signal based logs reopening unavailable!"
         
     | 
| 
       403 
428 
     | 
    
         
             
                  end
         
     | 
| 
       404 
     | 
    
         
            -
             
     | 
| 
       405 
     | 
    
         
            -
                  if Puma.jruby?
         
     | 
| 
       406 
     | 
    
         
            -
                    Signal.trap("INT") do
         
     | 
| 
       407 
     | 
    
         
            -
                      @status = :exit
         
     | 
| 
       408 
     | 
    
         
            -
                      graceful_stop
         
     | 
| 
       409 
     | 
    
         
            -
                      exit
         
     | 
| 
       410 
     | 
    
         
            -
                    end
         
     | 
| 
       411 
     | 
    
         
            -
                  end
         
     | 
| 
       412 
429 
     | 
    
         
             
                end
         
     | 
| 
       413 
430 
     | 
    
         
             
              end
         
     | 
| 
       414 
431 
     | 
    
         
             
            end
         
     |