puma 2.9.2 → 2.10.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 +4 -4
- data/History.txt +30 -1
- data/README.md +2 -2
- data/ext/puma_http11/mini_ssl.c +51 -1
- data/lib/puma/binder.rb +1 -0
- data/lib/puma/cli.rb +6 -5
- data/lib/puma/cluster.rb +21 -1
- data/lib/puma/configuration.rb +28 -5
- data/lib/puma/const.rb +2 -2
- data/lib/puma/thread_pool.rb +7 -1
- data/test/test_thread_pool.rb +24 -0
- data/tools/jungle/init.d/README.md +1 -1
- metadata +4 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2765b2cc720002160a156261825e5c66dcb9fba4
         | 
| 4 | 
            +
              data.tar.gz: d86005b282c74c803e773f12deeff31f039ee38b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 50322764a2f4962dbda6b6f042a7172493363928829140e4b896cf359285cc8ea4de0830afb9c21bed42aae465f4a04cfce700a9d9cb9a6cfe9e77084ee58e5e
         | 
| 7 | 
            +
              data.tar.gz: a8e2ea53d31c3f6418fcd9aa2e6d87ae17068fd8bb393d72ec46596b89996b0ab7199a6a6ec747697f4e2977af4229a87fcb3507dac7964e2670fbda16820f1b
         | 
    
        data/History.txt
    CHANGED
    
    | @@ -1,4 +1,33 @@ | |
| 1 | 
            -
            === 2. | 
| 1 | 
            +
            === 2.10.0 / 2014-11-23
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * 3 minor features:
         | 
| 4 | 
            +
              * Added on_worker_shutdown hook mechanism
         | 
| 5 | 
            +
              * Allow binding to ipv6 addresses for ssl URIs
         | 
| 6 | 
            +
              * Warn about any threads started during app preload
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            * 5 bug fixes:
         | 
| 9 | 
            +
              * Clean out a threads local data before doing work
         | 
| 10 | 
            +
              * Disable SSLv3. Fixes #591
         | 
| 11 | 
            +
              * First change the directory to use the correct Gemfile.
         | 
| 12 | 
            +
              * Only use config.ru binds if specified. Fixes #606
         | 
| 13 | 
            +
              * Strongish cipher suite with FS support for some browsers
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * 2 doc changes:
         | 
| 16 | 
            +
              * Change umask examples to more permissive values
         | 
| 17 | 
            +
              * fix typo in README.md
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * 9 Merged PRs:
         | 
| 20 | 
            +
              * Merge pull request #560 from raskhadafi/prune_bundler-bug
         | 
| 21 | 
            +
              * Merge pull request #566 from sheltond/master
         | 
| 22 | 
            +
              * Merge pull request #593 from andruby/patch-1
         | 
| 23 | 
            +
              * Merge pull request #594 from hassox/thread-cleanliness
         | 
| 24 | 
            +
              * Merge pull request #596 from burningTyger/patch-1
         | 
| 25 | 
            +
              * Merge pull request #601 from sorentwo/friendly-umask
         | 
| 26 | 
            +
              * Merge pull request #602 from 1334/patch-1
         | 
| 27 | 
            +
              * Merge pull request #608 from Gu1/master
         | 
| 28 | 
            +
              * Merge remote-tracking branch 'origin/pr/538'
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            === 2.9.2 / 2014-10-25
         | 
| 2 31 |  | 
| 3 32 | 
             
            * 8 bug fixes:
         | 
| 4 33 | 
             
              * Fix puma-wild handling a restart properly. Fixes #550
         | 
    
        data/README.md
    CHANGED
    
    | @@ -116,7 +116,7 @@ If you're preloading your application and using ActiveRecord, it's recommend you | |
| 116 116 | 
             
                    ActiveRecord::Base.establish_connection
         | 
| 117 117 | 
             
                  end
         | 
| 118 118 | 
             
                end
         | 
| 119 | 
            -
             | 
| 119 | 
            +
             | 
| 120 120 | 
             
            When you use preload_app, your new code goes all in the master process, and is then copied in the workers (meaning it’s only compatible with cluster mode). General rule is to use preload_app when your workers die often and need fast starts. If you don’t have many workers, you probably should not use preload_app.
         | 
| 121 121 |  | 
| 122 122 | 
             
            Note that preload_app can’t be used with phased restart, since phased restart kills and restarts workers one-by-one, and preload_app is all about copying the code of master into the workers.
         | 
| @@ -133,7 +133,7 @@ Want to use UNIX Sockets instead of TCP (which can provide a 5-10% performance b | |
| 133 133 |  | 
| 134 134 | 
             
            If you need to change the permissions of the UNIX socket, just add a umask parameter:
         | 
| 135 135 |  | 
| 136 | 
            -
                $ puma -b 'unix:///var/run/puma.sock?umask= | 
| 136 | 
            +
                $ puma -b 'unix:///var/run/puma.sock?umask=0111'
         | 
| 137 137 |  | 
| 138 138 | 
             
            Need a bit of security? Use SSL sockets!
         | 
| 139 139 |  | 
    
        data/ext/puma_http11/mini_ssl.c
    CHANGED
    
    | @@ -3,6 +3,7 @@ | |
| 3 3 | 
             
            #include <rubyio.h>
         | 
| 4 4 | 
             
            #include <openssl/bio.h>
         | 
| 5 5 | 
             
            #include <openssl/ssl.h>
         | 
| 6 | 
            +
            #include <openssl/dh.h>
         | 
| 6 7 | 
             
            #include <openssl/err.h>
         | 
| 7 8 |  | 
| 8 9 | 
             
            typedef struct {
         | 
| @@ -36,6 +37,42 @@ ms_conn* engine_alloc(VALUE klass, VALUE* obj) { | |
| 36 37 | 
             
              return conn;
         | 
| 37 38 | 
             
            }
         | 
| 38 39 |  | 
| 40 | 
            +
            DH *get_dh1024() {
         | 
| 41 | 
            +
              /* `openssl dhparam 1024 -C`
         | 
| 42 | 
            +
               * -----BEGIN DH PARAMETERS-----
         | 
| 43 | 
            +
               * MIGHAoGBALPwcEv0OstmQCZdfHw0N5r+07lmXMxkpQacy1blwj0LUqC+Divp6pBk
         | 
| 44 | 
            +
               * usTJ9W2/dOYr1X7zi6yXNLp4oLzc/31PUL3D9q8CpGS7vPz5gijKSw9BwCTT5z9+
         | 
| 45 | 
            +
               * KF9v46qw8XqT5HHV87sWFlGQcVFq+pEkA2kPikkKZ/X/CCcpCAV7AgEC
         | 
| 46 | 
            +
               * -----END DH PARAMETERS-----
         | 
| 47 | 
            +
               */
         | 
| 48 | 
            +
              static unsigned char dh1024_p[] = {
         | 
| 49 | 
            +
                0xB3,0xF0,0x70,0x4B,0xF4,0x3A,0xCB,0x66,0x40,0x26,0x5D,0x7C,
         | 
| 50 | 
            +
                0x7C,0x34,0x37,0x9A,0xFE,0xD3,0xB9,0x66,0x5C,0xCC,0x64,0xA5,
         | 
| 51 | 
            +
                0x06,0x9C,0xCB,0x56,0xE5,0xC2,0x3D,0x0B,0x52,0xA0,0xBE,0x0E,
         | 
| 52 | 
            +
                0x2B,0xE9,0xEA,0x90,0x64,0xBA,0xC4,0xC9,0xF5,0x6D,0xBF,0x74,
         | 
| 53 | 
            +
                0xE6,0x2B,0xD5,0x7E,0xF3,0x8B,0xAC,0x97,0x34,0xBA,0x78,0xA0,
         | 
| 54 | 
            +
                0xBC,0xDC,0xFF,0x7D,0x4F,0x50,0xBD,0xC3,0xF6,0xAF,0x02,0xA4,
         | 
| 55 | 
            +
                0x64,0xBB,0xBC,0xFC,0xF9,0x82,0x28,0xCA,0x4B,0x0F,0x41,0xC0,
         | 
| 56 | 
            +
                0x24,0xD3,0xE7,0x3F,0x7E,0x28,0x5F,0x6F,0xE3,0xAA,0xB0,0xF1,
         | 
| 57 | 
            +
                0x7A,0x93,0xE4,0x71,0xD5,0xF3,0xBB,0x16,0x16,0x51,0x90,0x71,
         | 
| 58 | 
            +
                0x51,0x6A,0xFA,0x91,0x24,0x03,0x69,0x0F,0x8A,0x49,0x0A,0x67,
         | 
| 59 | 
            +
                0xF5,0xFF,0x08,0x27,0x29,0x08,0x05,0x7B
         | 
| 60 | 
            +
              };
         | 
| 61 | 
            +
              static unsigned char dh1024_g[] = { 0x02 };
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              DH *dh;
         | 
| 64 | 
            +
              dh = DH_new();
         | 
| 65 | 
            +
              dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
         | 
| 66 | 
            +
              dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              if ((dh->p == NULL) || (dh->g == NULL)) {
         | 
| 69 | 
            +
                DH_free(dh);
         | 
| 70 | 
            +
                return NULL;
         | 
| 71 | 
            +
              }
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              return dh;
         | 
| 74 | 
            +
            }
         | 
| 75 | 
            +
             | 
| 39 76 | 
             
            VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
         | 
| 40 77 | 
             
              VALUE obj;
         | 
| 41 78 | 
             
              SSL_CTX* ctx;
         | 
| @@ -54,7 +91,20 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) { | |
| 54 91 |  | 
| 55 92 | 
             
              SSL_CTX_use_certificate_file(ctx, RSTRING_PTR(cert), SSL_FILETYPE_PEM);
         | 
| 56 93 | 
             
              SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
         | 
| 57 | 
            -
               | 
| 94 | 
            +
              
         | 
| 95 | 
            +
              SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE);
         | 
| 96 | 
            +
              SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              DH *dh = get_dh1024();
         | 
| 101 | 
            +
              SSL_CTX_set_tmp_dh(ctx, dh);
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
         | 
| 104 | 
            +
              if (ecdh) {
         | 
| 105 | 
            +
                SSL_CTX_set_tmp_ecdh(ctx, ecdh);
         | 
| 106 | 
            +
                EC_KEY_free(ecdh);
         | 
| 107 | 
            +
              }
         | 
| 58 108 |  | 
| 59 109 | 
             
              ssl =  SSL_new(ctx);
         | 
| 60 110 | 
             
              conn->ssl = ssl;
         | 
    
        data/lib/puma/binder.rb
    CHANGED
    
    | @@ -227,6 +227,7 @@ module Puma | |
| 227 227 | 
             
                                     optimize_for_latency=true, backlog=1024)
         | 
| 228 228 | 
             
                  require 'puma/minissl'
         | 
| 229 229 |  | 
| 230 | 
            +
                  host = host[1..-2] if host[0..0] == '['
         | 
| 230 231 | 
             
                  s = TCPServer.new(host, port)
         | 
| 231 232 | 
             
                  if optimize_for_latency
         | 
| 232 233 | 
             
                    s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
         | 
    
        data/lib/puma/cli.rb
    CHANGED
    
    | @@ -99,6 +99,7 @@ module Puma | |
| 99 99 | 
             
                    :binds => [],
         | 
| 100 100 | 
             
                    :workers => 0,
         | 
| 101 101 | 
             
                    :daemon => false,
         | 
| 102 | 
            +
                    :before_worker_shutdown => [],
         | 
| 102 103 | 
             
                    :before_worker_boot => [],
         | 
| 103 104 | 
             
                    :after_worker_boot => []
         | 
| 104 105 | 
             
                  }
         | 
| @@ -228,7 +229,7 @@ module Puma | |
| 228 229 |  | 
| 229 230 | 
             
                    cfg = @config.dup
         | 
| 230 231 |  | 
| 231 | 
            -
                    [ :logger, :before_worker_boot, :after_worker_boot, :on_restart ].each { |o| cfg.options.delete o }
         | 
| 232 | 
            +
                    [ :logger, :before_worker_shutdown, :before_worker_boot, :after_worker_boot, :on_restart ].each { |o| cfg.options.delete o }
         | 
| 232 233 |  | 
| 233 234 | 
             
                    state["config"] = cfg
         | 
| 234 235 |  | 
| @@ -454,6 +455,10 @@ module Puma | |
| 454 455 | 
             
                    exit 1
         | 
| 455 456 | 
             
                  end
         | 
| 456 457 |  | 
| 458 | 
            +
                  if dir = @options[:directory]
         | 
| 459 | 
            +
                    Dir.chdir dir
         | 
| 460 | 
            +
                  end
         | 
| 461 | 
            +
             | 
| 457 462 | 
             
                  if prune_bundler? && defined?(Bundler)
         | 
| 458 463 | 
             
                    puma = Bundler.rubygems.loaded_specs("puma")
         | 
| 459 464 |  | 
| @@ -483,10 +488,6 @@ module Puma | |
| 483 488 | 
             
                    log "! Unable to prune Bundler environment, continuing"
         | 
| 484 489 | 
             
                  end
         | 
| 485 490 |  | 
| 486 | 
            -
                  if dir = @options[:directory]
         | 
| 487 | 
            -
                    Dir.chdir dir
         | 
| 488 | 
            -
                  end
         | 
| 489 | 
            -
             | 
| 490 491 | 
             
                  set_rack_environment
         | 
| 491 492 |  | 
| 492 493 | 
             
                  if clustered?
         | 
    
        data/lib/puma/cluster.rb
    CHANGED
    
    | @@ -73,7 +73,7 @@ module Puma | |
| 73 73 |  | 
| 74 74 | 
             
                  def term
         | 
| 75 75 | 
             
                    begin
         | 
| 76 | 
            -
                      if @first_term_sent && (Time.new - @first_term_sent) >  | 
| 76 | 
            +
                      if @first_term_sent && (Time.new - @first_term_sent) > @options[:worker_shutdown_timeout]
         | 
| 77 77 | 
             
                        @signal = "KILL"
         | 
| 78 78 | 
             
                      else
         | 
| 79 79 | 
             
                        @first_term_sent ||= Time.new
         | 
| @@ -228,6 +228,10 @@ module Puma | |
| 228 228 |  | 
| 229 229 | 
             
                  server.run.join
         | 
| 230 230 |  | 
| 231 | 
            +
                  # Invoke any worker shutdown hooks so they can prevent the worker
         | 
| 232 | 
            +
                  # exiting until any background operations are completed
         | 
| 233 | 
            +
                  hooks = @options[:before_worker_shutdown]
         | 
| 234 | 
            +
                  hooks.each { |h| h.call(index) }
         | 
| 231 235 | 
             
                ensure
         | 
| 232 236 | 
             
                  @worker_write.close
         | 
| 233 237 | 
             
                end
         | 
| @@ -278,9 +282,25 @@ module Puma | |
| 278 282 |  | 
| 279 283 | 
             
                  log "* Process workers: #{@options[:workers]}"
         | 
| 280 284 |  | 
| 285 | 
            +
                  before = Thread.list
         | 
| 286 | 
            +
             | 
| 281 287 | 
             
                  if preload?
         | 
| 282 288 | 
             
                    log "* Preloading application"
         | 
| 283 289 | 
             
                    load_and_bind
         | 
| 290 | 
            +
             | 
| 291 | 
            +
                    after = Thread.list
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                    if after.size > before.size
         | 
| 294 | 
            +
                      threads = (after - before)
         | 
| 295 | 
            +
                      if threads.first.respond_to? :backtrace
         | 
| 296 | 
            +
                        log "! WARNING: Detected #{after.size-before.size} Thread(s) started in app boot:"
         | 
| 297 | 
            +
                        threads.each do |t|
         | 
| 298 | 
            +
                          log "! #{t.inspect} - #{t.backtrace.first}"
         | 
| 299 | 
            +
                        end
         | 
| 300 | 
            +
                      else
         | 
| 301 | 
            +
                        log "! WARNING: Detected #{after.size-before.size} Thread(s) started in app boot"
         | 
| 302 | 
            +
                      end
         | 
| 303 | 
            +
                    end
         | 
| 284 304 | 
             
                  else
         | 
| 285 305 | 
             
                    log "* Phased restart available"
         | 
| 286 306 |  | 
    
        data/lib/puma/configuration.rb
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            module Puma
         | 
| 2 2 |  | 
| 3 | 
            -
              # The CLI exports  | 
| 3 | 
            +
              # The CLI exports its Configuration object here to allow
         | 
| 4 4 | 
             
              # apps to pick it up. An app needs to use it conditionally though
         | 
| 5 5 | 
             
              # since it is not set if the app is launched via another
         | 
| 6 6 | 
             
              # mechanism than the CLI class.
         | 
| @@ -15,15 +15,18 @@ module Puma | |
| 15 15 | 
             
                DefaultTCPHost = "0.0.0.0"
         | 
| 16 16 | 
             
                DefaultTCPPort = 9292
         | 
| 17 17 | 
             
                DefaultWorkerTimeout = 60
         | 
| 18 | 
            +
                DefaultWorkerShutdownTimeout = 30
         | 
| 18 19 |  | 
| 19 20 | 
             
                def initialize(options)
         | 
| 20 21 | 
             
                  @options = options
         | 
| 21 22 | 
             
                  @options[:mode] ||= :http
         | 
| 22 23 | 
             
                  @options[:binds] ||= []
         | 
| 23 24 | 
             
                  @options[:on_restart] ||= []
         | 
| 25 | 
            +
                  @options[:before_worker_shutdown] ||= []
         | 
| 24 26 | 
             
                  @options[:before_worker_boot] ||= []
         | 
| 25 27 | 
             
                  @options[:after_worker_boot] ||= []
         | 
| 26 28 | 
             
                  @options[:worker_timeout] ||= DefaultWorkerTimeout
         | 
| 29 | 
            +
                  @options[:worker_shutdown_timeout] ||= DefaultWorkerShutdownTimeout
         | 
| 27 30 | 
             
                end
         | 
| 28 31 |  | 
| 29 32 | 
             
                attr_reader :options
         | 
| @@ -82,7 +85,7 @@ module Puma | |
| 82 85 | 
             
                  @options[:rackup] || DefaultRackup
         | 
| 83 86 | 
             
                end
         | 
| 84 87 |  | 
| 85 | 
            -
                # Load the specified rackup file, pull  | 
| 88 | 
            +
                # Load the specified rackup file, pull options from
         | 
| 86 89 | 
             
                # the rackup file, and set @app.
         | 
| 87 90 | 
             
                #
         | 
| 88 91 | 
             
                def app
         | 
| @@ -96,11 +99,15 @@ module Puma | |
| 96 99 | 
             
                    app, options = Rack::Builder.parse_file rackup
         | 
| 97 100 | 
             
                    @options.merge! options
         | 
| 98 101 |  | 
| 102 | 
            +
                    config_ru_binds = []
         | 
| 103 | 
            +
             | 
| 99 104 | 
             
                    options.each do |key,val|
         | 
| 100 105 | 
             
                      if key.to_s[0,4] == "bind"
         | 
| 101 | 
            -
                         | 
| 106 | 
            +
                        config_ru_binds << val
         | 
| 102 107 | 
             
                      end
         | 
| 103 108 | 
             
                    end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                    @options[:binds] = config_ru_binds unless config_ru_binds.empty?
         | 
| 104 111 | 
             
                  end
         | 
| 105 112 |  | 
| 106 113 | 
             
                  if @options[:mode] == :tcp
         | 
| @@ -301,6 +308,17 @@ module Puma | |
| 301 308 | 
             
                    @options[:workers] = count.to_i
         | 
| 302 309 | 
             
                  end
         | 
| 303 310 |  | 
| 311 | 
            +
                  # *Cluster mode only* Code to run immediately before a worker shuts
         | 
| 312 | 
            +
                  # down (after it has finished processing HTTP requests). These hooks
         | 
| 313 | 
            +
                  # can block if necessary to wait for background operations unknown
         | 
| 314 | 
            +
                  # to puma to finish before the process terminates.
         | 
| 315 | 
            +
                  #
         | 
| 316 | 
            +
                  # This can be called multiple times to add hooks.
         | 
| 317 | 
            +
                  #
         | 
| 318 | 
            +
                  def on_worker_shutdown(&block)
         | 
| 319 | 
            +
                    @options[:before_worker_shutdown] << block
         | 
| 320 | 
            +
                  end
         | 
| 321 | 
            +
             | 
| 304 322 | 
             
                  # *Cluster mode only* Code to run when a worker boots to setup
         | 
| 305 323 | 
             
                  # the process before booting the app.
         | 
| 306 324 | 
             
                  #
         | 
| @@ -338,7 +356,7 @@ module Puma | |
| 338 356 | 
             
                    @options[:preload_app] = answer
         | 
| 339 357 | 
             
                  end
         | 
| 340 358 |  | 
| 341 | 
            -
                  # Use +obj+ or +block+ as the low  | 
| 359 | 
            +
                  # Use +obj+ or +block+ as the low level error handler. This allows a config file to
         | 
| 342 360 | 
             
                  # change the default error on the server.
         | 
| 343 361 | 
             
                  #
         | 
| 344 362 | 
             
                  def lowlevel_error_handler(obj=nil, &block)
         | 
| @@ -347,7 +365,7 @@ module Puma | |
| 347 365 | 
             
                    @options[:lowlevel_error_handler] = obj
         | 
| 348 366 | 
             
                  end
         | 
| 349 367 |  | 
| 350 | 
            -
                  # This option is used to allow your app and  | 
| 368 | 
            +
                  # This option is used to allow your app and its gems to be
         | 
| 351 369 | 
             
                  # properly reloaded when not using preload.
         | 
| 352 370 | 
             
                  #
         | 
| 353 371 | 
             
                  # When set, if puma detects that it's been invoked in the
         | 
| @@ -372,6 +390,11 @@ module Puma | |
| 372 390 | 
             
                  def worker_timeout(timeout)
         | 
| 373 391 | 
             
                    @options[:worker_timeout] = timeout
         | 
| 374 392 | 
             
                  end
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                  # *Cluster mode only* Set the timeout for worker shutdown
         | 
| 395 | 
            +
                  def worker_shutdown_timeout(timeout)
         | 
| 396 | 
            +
                    @options[:worker_shutdown_timeout] = timeout
         | 
| 397 | 
            +
                  end
         | 
| 375 398 | 
             
                end
         | 
| 376 399 | 
             
              end
         | 
| 377 400 | 
             
            end
         | 
    
        data/lib/puma/const.rb
    CHANGED
    
    | @@ -28,8 +28,8 @@ module Puma | |
| 28 28 | 
             
              # too taxing on performance.
         | 
| 29 29 | 
             
              module Const
         | 
| 30 30 |  | 
| 31 | 
            -
                PUMA_VERSION = VERSION = "2. | 
| 32 | 
            -
                CODE_NAME = " | 
| 31 | 
            +
                PUMA_VERSION = VERSION = "2.10.0".freeze
         | 
| 32 | 
            +
                CODE_NAME = "Robots on Comets".freeze
         | 
| 33 33 |  | 
| 34 34 | 
             
                FAST_TRACK_KA_TIMEOUT = 0.2
         | 
| 35 35 |  | 
    
        data/lib/puma/thread_pool.rb
    CHANGED
    
    | @@ -89,6 +89,10 @@ module Puma | |
| 89 89 |  | 
| 90 90 | 
             
                      break unless continue
         | 
| 91 91 |  | 
| 92 | 
            +
                      Thread.current.keys.each do |key|
         | 
| 93 | 
            +
                        Thread.current[key] = nil unless key == :__recursive_key__
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
             | 
| 92 96 | 
             
                      block.call(work, *extra)
         | 
| 93 97 | 
             
                    end
         | 
| 94 98 |  | 
| @@ -176,7 +180,9 @@ module Puma | |
| 176 180 |  | 
| 177 181 | 
             
                  # Use this instead of #each so that we don't stop in the middle
         | 
| 178 182 | 
             
                  # of each and see a mutated object mid #each
         | 
| 179 | 
            -
                   | 
| 183 | 
            +
                  if !@workers.empty?
         | 
| 184 | 
            +
                      @workers.first.join until @workers.empty?
         | 
| 185 | 
            +
                  end
         | 
| 180 186 |  | 
| 181 187 | 
             
                  @spawned = 0
         | 
| 182 188 | 
             
                  @workers = []
         | 
    
        data/test/test_thread_pool.rb
    CHANGED
    
    | @@ -153,4 +153,28 @@ class TestThreadPool < Test::Unit::TestCase | |
| 153 153 |  | 
| 154 154 | 
             
                assert_equal 1, pool.spawned
         | 
| 155 155 | 
             
              end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              def test_cleanliness
         | 
| 158 | 
            +
                values = []
         | 
| 159 | 
            +
                n = 100
         | 
| 160 | 
            +
                mutex = Mutex.new
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                finished = false
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                pool = new_pool(1,1) {
         | 
| 165 | 
            +
                  mutex.synchronize { values.push Thread.current[:foo] }
         | 
| 166 | 
            +
                  Thread.current[:foo] = :hai
         | 
| 167 | 
            +
                  Thread.pass until finished
         | 
| 168 | 
            +
                }
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                n.times { pool << 1 }
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                finished = true
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                pause
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                assert_equal n,  values.length
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                assert_equal [], values.compact
         | 
| 179 | 
            +
              end
         | 
| 156 180 | 
             
            end
         | 
| @@ -26,7 +26,7 @@ Puma apps are held in /etc/puma.conf by default. It's mainly a CSV file and ever | |
| 26 26 |  | 
| 27 27 | 
             
            You can add an instance by editing the file or running the following command:
         | 
| 28 28 |  | 
| 29 | 
            -
                sudo /etc/init.d/puma add /path/to/app user /path/to/app/config/puma.rb /path/to/app/ | 
| 29 | 
            +
                sudo /etc/init.d/puma add /path/to/app user /path/to/app/config/puma.rb /path/to/app/log/puma.log
         | 
| 30 30 |  | 
| 31 31 | 
             
            The config and log paths are optional parameters and default to:
         | 
| 32 32 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: puma
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.10.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Evan Phoenix
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014- | 
| 11 | 
            +
            date: 2014-11-24 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rack
         | 
| @@ -64,14 +64,14 @@ dependencies: | |
| 64 64 | 
             
                requirements:
         | 
| 65 65 | 
             
                - - "~>"
         | 
| 66 66 | 
             
                  - !ruby/object:Gem::Version
         | 
| 67 | 
            -
                    version: '3. | 
| 67 | 
            +
                    version: '3.12'
         | 
| 68 68 | 
             
              type: :development
         | 
| 69 69 | 
             
              prerelease: false
         | 
| 70 70 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 71 71 | 
             
                requirements:
         | 
| 72 72 | 
             
                - - "~>"
         | 
| 73 73 | 
             
                  - !ruby/object:Gem::Version
         | 
| 74 | 
            -
                    version: '3. | 
| 74 | 
            +
                    version: '3.12'
         | 
| 75 75 | 
             
            description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
         | 
| 76 76 | 
             
              for Ruby/Rack applications. Puma is intended for use in both development and production
         | 
| 77 77 | 
             
              environments. In order to get the best throughput, it is highly recommended that
         |