Hello community,

here is the log from the commit of package rubygem-puma for openSUSE:Factory 
checked in at 2016-04-14 13:06:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-puma (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-puma.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-puma"

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-puma/rubygem-puma.changes        
2016-03-26 18:14:25.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.rubygem-puma.new/rubygem-puma.changes   
2016-04-14 13:06:55.000000000 +0200
@@ -1,0 +2,64 @@
+Tue Apr 12 04:31:32 UTC 2016 - co...@suse.com
+
+- updated to version 3.4.0
+ see installed History.txt
+
+  === 3.4.0 / 2016-04-07
+  
+  * 2 minor features:
+    * Add ability to force threads to stop on shutdown. Fixes #938
+    * Detect and commit seppuku when fork(2) fails. Fixes #529
+  
+  * 3 unknowns:
+    * Ignore errors trying to update the backport tables. Fixes #788
+    * Invoke the lowlevel_error in more places to allow for exception 
tracking. Fixes #894
+    * Update the query string when an absolute URI is used. Fixes #937
+  
+  * 5 doc fixes:
+    * Add Process Monitors section to top-level README
+    * Better document the hooks. Fixes #840
+    * docs/system.md sample config refinements and elaborations
+    * Fix typos at couple of places.
+    * Cleanup warnings
+  
+  * 3 PRs merged:
+    * Merge pull request #945 from dekellum/systemd-docs-refined
+    * Merge pull request #946 from vipulnsward/rm-pid
+    * Merge pull request #947 from vipulnsward/housekeeping-typos
+
+-------------------------------------------------------------------
+Wed Apr  6 06:29:33 UTC 2016 - co...@suse.com
+
+- updated to version 3.3.0
+ see installed History.txt
+
+  === 3.3.0 / 2016-04-05
+  
+  * 2 minor features:
+    * Allow overriding options of Configuration object
+    * Rename to inherit_ssl_listener like inherit_tcp|unix
+  
+  * 2 doc fixes:
+    * Add docs/systemd.md (with socket activation sub-section)
+    * Document UNIX signals with cluster on README.md
+  
+  * 3 PRs merged:
+    * Merge pull request #936 from 
prathamesh-sonpatki/allow-overriding-config-options
+    * Merge pull request #940 from kyledrake/signalsdoc
+    * Merge pull request #942 from dekellum/socket-activate-improve
+  
+  === 3.2.0 / 2016-03-20
+  
+  * 1 deprecation removal:
+    * Delete capistrano.rb
+  
+  * 3 bug fixes:
+    * Detect gems.rb as well as Gemfile
+    * Simplify and fix logic for directory to use when restarting for all 
phases
+    * Speed up phased-restart start
+  
+  * 2 PRs merged:
+    * Merge pull request #927 from jlecour/gemfile_variants
+    * Merge pull request #931 from joneslee85/patch-10
+
+-------------------------------------------------------------------

Old:
----
  puma-3.1.1.gem

New:
----
  puma-3.4.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-puma.spec ++++++
--- /var/tmp/diff_new_pack.YtsB38/_old  2016-04-14 13:06:55.000000000 +0200
+++ /var/tmp/diff_new_pack.YtsB38/_new  2016-04-14 13:06:55.000000000 +0200
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-puma
-Version:        3.1.1
+Version:        3.4.0
 Release:        0
 %define mod_name puma
 %define mod_full_name %{mod_name}-%{version}

++++++ puma-3.1.1.gem -> puma-3.4.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/History.txt new/History.txt
--- old/History.txt     2016-03-18 05:32:21.000000000 +0100
+++ new/History.txt     2016-04-08 00:02:21.000000000 +0200
@@ -1,3 +1,55 @@
+=== 3.4.0 / 2016-04-07
+
+* 2 minor features:
+  * Add ability to force threads to stop on shutdown. Fixes #938
+  * Detect and commit seppuku when fork(2) fails. Fixes #529
+
+* 3 unknowns:
+  * Ignore errors trying to update the backport tables. Fixes #788
+  * Invoke the lowlevel_error in more places to allow for exception tracking. 
Fixes #894
+  * Update the query string when an absolute URI is used. Fixes #937
+
+* 5 doc fixes:
+  * Add Process Monitors section to top-level README
+  * Better document the hooks. Fixes #840
+  * docs/system.md sample config refinements and elaborations
+  * Fix typos at couple of places.
+  * Cleanup warnings
+
+* 3 PRs merged:
+  * Merge pull request #945 from dekellum/systemd-docs-refined
+  * Merge pull request #946 from vipulnsward/rm-pid
+  * Merge pull request #947 from vipulnsward/housekeeping-typos
+
+=== 3.3.0 / 2016-04-05
+
+* 2 minor features:
+  * Allow overriding options of Configuration object
+  * Rename to inherit_ssl_listener like inherit_tcp|unix
+
+* 2 doc fixes:
+  * Add docs/systemd.md (with socket activation sub-section)
+  * Document UNIX signals with cluster on README.md
+
+* 3 PRs merged:
+  * Merge pull request #936 from 
prathamesh-sonpatki/allow-overriding-config-options
+  * Merge pull request #940 from kyledrake/signalsdoc
+  * Merge pull request #942 from dekellum/socket-activate-improve
+
+=== 3.2.0 / 2016-03-20
+
+* 1 deprecation removal:
+  * Delete capistrano.rb
+
+* 3 bug fixes:
+  * Detect gems.rb as well as Gemfile
+  * Simplify and fix logic for directory to use when restarting for all phases
+  * Speed up phased-restart start
+
+* 2 PRs merged:
+  * Merge pull request #927 from jlecour/gemfile_variants
+  * Merge pull request #931 from joneslee85/patch-10
+
 === 3.1.1 / 2016-03-17
 
 * 4 bug fixes:
@@ -951,7 +1003,7 @@
 
 === 1.5.0 / 2012-07-19
 
-* 7 contributers to this release:
+* 7 contributors to this release:
   * Christian Mayer
   * Darío Javier Cravero
   * Dirkjan Bussink
@@ -999,7 +1051,7 @@
   * Only stop the status server if it's started. Fixes #84
   * Set RACK_ENV early in cli also. Fixes #78
 
-* 1 new contributer:
+* 1 new contributor:
   * Jesse Cooke
 
 === 1.2.2 / 2012-04-28
@@ -1035,9 +1087,9 @@
     * Fix reporting https only on a true SSL connection
     * Set the default content type to 'text/plain'. Fixes #63
     * Use REUSEADDR. Fixes #60
-    * Shutdown gracefull on SIGTERM. Fixes #53
+    * Shutdown gracefully on SIGTERM. Fixes #53
 
- 2 new contributers:
+ 2 new contributors:
 
    * Seamus Abshere
    * Steve Richert
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Manifest.txt new/Manifest.txt
--- old/Manifest.txt    2016-03-18 05:32:21.000000000 +0100
+++ new/Manifest.txt    2016-04-08 00:02:21.000000000 +0200
@@ -11,6 +11,7 @@
 docs/config.md
 docs/nginx.md
 docs/signals.md
+docs/systemd.md
 ext/puma_http11/PumaHttp11Service.java
 ext/puma_http11/ext_help.h
 ext/puma_http11/extconf.rb
@@ -29,7 +30,6 @@
 lib/puma/accept_nonblock.rb
 lib/puma/app/status.rb
 lib/puma/binder.rb
-lib/puma/capistrano.rb
 lib/puma/cli.rb
 lib/puma/client.rb
 lib/puma/cluster.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2016-03-18 05:32:21.000000000 +0100
+++ new/README.md       2016-04-08 00:02:21.000000000 +0200
@@ -238,7 +238,7 @@
 
 No code is shared between the current and restarted process, so it should be 
safe to issue a restart any place where you would manually stop Puma and start 
it again.
 
-If the new process is unable to load, it will simply exit. You should 
therefore run Puma under a supervisor when using it in production.
+If the new process is unable to load, it will simply exit. You should 
therefore run Puma under a process monitor (see below) when using it in 
production.
 
 ### Normal vs Hot vs Phased Restart
 
@@ -252,6 +252,21 @@
 
 If you perform a lot of database migrations, you probably should not use 
phased restart and use a normal/hot restart instead (pumactl restart). That 
way, no code is shared while deploying (in that case, preload_app might help 
for quicker deployment, see below).
 
+### Puma Signals
+
+Puma cluster responds to these signals:
+
+- `TTIN` increment the worker count by 1
+- `TTOU` decrement the worker count by 1
+- `TERM` send `TERM` to worker. Worker will attempt to finish then exit.
+- `USR2` restart workers
+- `USR1` restart workers in phases, a rolling restart.
+- `HUP`  reopen log files defined in stdout_redirect configuration parameter
+- `INT` equivalent of sending Ctrl-C to cluster. Will attempt to finish then 
exit.
+- `CHLD`
+
+A detailed guide to using UNIX signals with Puma can be found in the [signals 
documentation](https://github.com/puma/puma/blob/master/docs/signals.md).
+
 ### Release Directory
 
 If you symlink releases into a common working directory (i.e., `/current` from 
Capistrano), Puma won't pick up your new changes when running phased restarts 
without additional configuration. You should set your working directory within 
Puma's config to specify the directory it should use. This is a change from 
earlier versions of Puma (< 2.15) that would infer the directory for you.
@@ -280,9 +295,15 @@
 
 `pumactl` is a simple CLI frontend to the control/status app described above.  
Please refer to `pumactl --help` for available commands.
 
-## Managing multiple Pumas / init.d / upstart scripts
+## Process Monitors
+
+Process monitors or supervisors will at minimum provide start of Puma
+on system boot. Modern process monitors like systemd or upstart
+further provide continuous monitoring and restarts for increased
+reliability in production environments:
 
-If you want an easy way to manage multiple scripts at once, check 
[tools/jungle](https://github.com/puma/puma/tree/master/tools/jungle) for 
init.d and upstart scripts.
+* [tools/jungle](https://github.com/puma/puma/tree/master/tools/jungle) for 
sysvinit (init.d) and upstart
+* [docs/systemd](https://github.com/puma/puma/blob/master/docs/systemd.md)
 
 ## Capistrano deployment
 
Files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docs/nginx.md new/docs/nginx.md
--- old/docs/nginx.md   2016-03-18 05:32:21.000000000 +0100
+++ new/docs/nginx.md   2016-04-08 00:02:21.000000000 +0200
@@ -34,7 +34,7 @@
     proxy_set_header Host $http_host;
 
     # If the file exists as a static file serve it directly without
-    # running all the other rewite tests on it
+    # running all the other rewrite tests on it
     if (-f $request_filename) {
       break;
     }
@@ -50,7 +50,7 @@
     # this is the meat of the rack page caching config
     # it adds .html to the end of the url and then checks
     # the filesystem for that file. If it exists, then we
-    # rewite the url to have explicit .html on the end
+    # rewrite the url to have explicit .html on the end
     # and then send it on its way to the next config rule.
     # if there is no file on the fs then it sets all the
     # necessary headers and proxies to our upstream pumas
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/docs/systemd.md new/docs/systemd.md
--- old/docs/systemd.md 1970-01-01 01:00:00.000000000 +0100
+++ new/docs/systemd.md 2016-04-08 00:02:21.000000000 +0200
@@ -0,0 +1,170 @@
+# systemd
+
+[systemd](https://www.freedesktop.org/wiki/Software/systemd/) is a
+commonly available init system (PID 1) on many Linux distributions. It
+offers process monitoring (including automatic restarts) and other
+useful features for running Puma in production. Below is a sample
+puma.service configuration file for systemd:
+
+~~~~
+[Unit]
+Description=Puma HTTP Server
+After=network.target
+
+# Uncomment for socket activation (see below)
+# Requires=puma.socket
+
+[Service]
+# Foreground process (do not use --daemon in ExecStart or config.rb)
+Type=simple
+
+# Preferably configure a non-privileged user
+# User=
+
+# Specify the path to your puma application root
+# WorkingDirectory=
+
+# Helpful for debugging socket activation, etc.
+# Environment=PUMA_DEBUG=1
+
+# The command to start Puma
+# Here we are using a binstub generated via:
+# `bundle binstubs puma --path ./sbin`
+# in the WorkingDirectory (replace <WD> below)
+# You can alternatively use `bundle exec --keep-file-descriptors puma`
+# ExecStart=<WD>/sbin/puma -b tcp://0.0.0.0:9292 -b 
ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem
+
+# Alternatively with a config file (in WorkingDirectory) and
+# comparable `bind` directives
+# ExecStart=<WD>/sbin/puma -C config.rb
+
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+~~~~
+
+See 
[systemd.exec](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)
+for additional details.
+
+## Socket Activation
+
+systemd and puma also support socket activation, where systemd opens
+the listening socket(s) in advance and provides them to the puma master
+process on startup. Among other advantages, this keeps listening
+sockets open across puma restarts and achieves graceful restarts. To
+use socket activation, configure one or more `ListenStream`
+sockets in a companion `*.socket` systemd config file. Here is a sample
+puma.socket, matching the ports used in the above puma.service:
+
+~~~~
+[Unit]
+Description=Puma HTTP Server Accept Sockets
+
+[Socket]
+ListenStream=0.0.0.0:9292
+ListenStream=0.0.0.0:9293
+
+# AF_UNIX domain socket
+# SocketUser, SocketGroup, etc. may be needed for Unix domain sockets
+# ListenStream=/run/puma.sock
+
+# Socket options matching Puma defaults
+NoDelay=true
+ReusePort=true
+Backlog=1024
+
+[Install]
+WantedBy=sockets.target
+~~~~
+
+See 
[systemd.socket](https://www.freedesktop.org/software/systemd/man/systemd.socket.html)
+for additional configuration details.
+
+Note that the above configurations will work with Puma in either
+single process or cluster mode.
+
+## Usage
+
+Without socket activation, use `systemctl` as root (e.g. via `sudo`) as
+with other system services:
+
+~~~~ sh
+# After installing or making changes to puma.service
+systemctl daemon-reload
+
+# Enable so it starts on boot
+systemctl enable puma.service
+
+# Initial start up.
+systemctl start puma.service
+
+# Check status
+systemctl status puma.service
+
+# A normal restart. Warning: listeners sockets will be closed
+# while a new puma process initializes.
+systemctl restart puma.service
+~~~~
+
+With socket activation, several but not all of these commands should
+be run for both socket and service:
+
+~~~~ sh
+# After installing or making changes to either puma.socket or
+# puma.service.
+systemctl daemon-reload
+
+# Enable both socket and service so they start on boot.  Alternatively
+# you could leave puma.service disabled and systemd will start it on
+# first use (with startup lag on first request)
+systemctl enable puma.socket puma.service
+
+# Initial start up. The Requires directive (see above) ensures the
+# socket is started before the service.
+systemctl start puma.socket puma.service
+
+# Check status of both socket and service.
+systemctl status puma.socket puma.service
+
+# A "hot" restart, with systemd keeping puma.socket listening and
+# providing to the new puma (master) instance.
+systemctl restart puma.service
+
+# A normal restart, needed to handle changes to
+# puma.socket, such as changing the ListenStream ports. Note
+# daemon-reload (above) should be run first.
+systemctl restart puma.socket puma.service
+~~~~
+
+Here is sample output from `systemctl status` with both service and
+socket running:
+
+~~~~
+● puma.socket - Puma HTTP Server Accept Sockets
+   Loaded: loaded (/etc/systemd/system/puma.socket; enabled; vendor preset: 
enabled)
+   Active: active (running) since Thu 2016-04-07 08:40:19 PDT; 1h 2min ago
+   Listen: 0.0.0.0:9233 (Stream)
+           0.0.0.0:9234 (Stream)
+
+Apr 07 08:40:19 hx systemd[874]: Listening on Puma HTTP Server Accept Sockets.
+
+● puma.service - Puma HTTP Server
+   Loaded: loaded (/etc/systemd/system/puma.service; enabled; vendor preset: 
enabled)
+   Active: active (running) since Thu 2016-04-07 08:40:19 PDT; 1h 2min ago
+ Main PID: 28320 (ruby)
+   CGroup: /system.slice/puma.service
+           ├─28320 puma 3.3.0 
(tcp://0.0.0.0:9233,ssl://0.0.0.0:9234?key=key.pem&cert=cert.pem) [app]
+           ├─28323 puma: cluster worker 0: 28320 [app]
+           └─28327 puma: cluster worker 1: 28320 [app]
+
+Apr 07 08:40:19 hx puma[28320]: Puma starting in cluster mode...
+Apr 07 08:40:19 hx puma[28320]: * Version 3.3.0 (ruby 2.2.4-p230), codename: 
Jovial Platypus
+Apr 07 08:40:19 hx puma[28320]: * Min threads: 0, max threads: 16
+Apr 07 08:40:19 hx puma[28320]: * Environment: production
+Apr 07 08:40:19 hx puma[28320]: * Process workers: 2
+Apr 07 08:40:19 hx puma[28320]: * Phased restart available
+Apr 07 08:40:19 hx puma[28320]: * Activated tcp://0.0.0.0:9233
+Apr 07 08:40:19 hx puma[28320]: * Activated 
ssl://0.0.0.0:9234?key=key.pem&cert=cert.pem
+Apr 07 08:40:19 hx puma[28320]: Use Ctrl-C to stop
+~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/binder.rb new/lib/puma/binder.rb
--- old/lib/puma/binder.rb      2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/binder.rb      2016-04-08 00:02:21.000000000 +0200
@@ -11,6 +11,7 @@
       @events = events
       @listeners = []
       @inherited_fds = {}
+      @activated_sockets = {}
       @unix_paths = []
 
       @proto_env = {
@@ -22,7 +23,7 @@
         "SCRIPT_NAME".freeze => ENV['SCRIPT_NAME'] || "",
 
         # I'd like to set a default CONTENT_TYPE here but some things
-        # depend on their not being a default set and infering
+        # depend on their not being a default set and inferring
         # it from the content. And so if i set it here, it won't
         # infer properly.
 
@@ -55,24 +56,23 @@
           fd, url = v.split(":", 2)
           @inherited_fds[url] = fd.to_i
           remove << k
-        end
-        if k =~ /LISTEN_FDS/ && ENV['LISTEN_PID'].to_i == $$
+        elsif k == 'LISTEN_FDS' && ENV['LISTEN_PID'].to_i == $$
           v.to_i.times do |num|
             fd = num + 3
             sock = TCPServer.for_fd(fd)
             begin
-              url = "unix://" + Socket.unpack_sockaddr_un(sock.getsockname)
+              key = [ :unix, Socket.unpack_sockaddr_un(sock.getsockname) ]
             rescue ArgumentError
               port, addr = Socket.unpack_sockaddr_in(sock.getsockname)
               if addr =~ /\:/
                 addr = "[#{addr}]"
               end
-              url = "tcp://#{addr}:#{port}"
+              key = [ :tcp, addr, port ]
             end
-            @inherited_fds[url] = sock
+            @activated_sockets[key] = sock
+            @events.debug "Registered #{key.join ':'} for activation from 
LISTEN_FDS"
           end
-          ENV.delete k
-          ENV.delete 'LISTEN_PID'
+          remove << k << 'LISTEN_PID'
         end
       end
 
@@ -89,6 +89,9 @@
           if fd = @inherited_fds.delete(str)
             logger.log "* Inherited #{str}"
             io = inherit_tcp_listener uri.host, uri.port, fd
+          elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
+            logger.log "* Activated #{str}"
+            io = inherit_tcp_listener uri.host, uri.port, sock
           else
             params = Util.parse_query uri.query
 
@@ -106,6 +109,9 @@
           if fd = @inherited_fds.delete(str)
             logger.log "* Inherited #{str}"
             io = inherit_unix_listener path, fd
+          elsif sock = @activated_sockets.delete([ :unix, path ])
+            logger.log "* Activated #{str}"
+            io = inherit_unix_listener path, sock
           else
             logger.log "* Listening on #{str}"
 
@@ -191,7 +197,10 @@
 
           if fd = @inherited_fds.delete(str)
             logger.log "* Inherited #{str}"
-            io = inherited_ssl_listener fd, ctx
+            io = inherit_ssl_listener fd, ctx
+          elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
+            logger.log "* Activated #{str}"
+            io = inherit_ssl_listener sock, ctx
           else
             logger.log "* Listening on #{str}"
             io = add_ssl_listener uri.host, uri.port, ctx
@@ -209,12 +218,7 @@
         logger.log "* Closing unused inherited connection: #{str}"
 
         begin
-          if fd.kind_of? TCPServer
-            fd.close
-          else
-            IO.for_fd(fd).close
-          end
-
+          IO.for_fd(fd).close
         rescue SystemCallError
         end
 
@@ -226,6 +230,17 @@
         end
       end
 
+      # Also close any unused activated sockets
+      @activated_sockets.each do |key, sock|
+        logger.log "* Closing unused activated socket: #{key.join ':'}"
+        begin
+          sock.close
+        rescue SystemCallError
+        end
+        # We have to unlink a unix socket path that's not being used
+        File.unlink key[1] if key[0] == :unix
+      end
+
     end
 
     # Tell the server to listen on host +host+, port +port+.
@@ -285,11 +300,15 @@
       s
     end
 
-    def inherited_ssl_listener(fd, ctx)
+    def inherit_ssl_listener(fd, ctx)
       require 'puma/minissl'
       MiniSSL.check
 
-      s = TCPServer.for_fd(fd)
+      if fd.kind_of? TCPServer
+        s = fd
+      else
+        s = TCPServer.for_fd(fd)
+      end
       ssl = MiniSSL::Server.new(s, ctx)
 
       env = @proto_env.dup
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/capistrano.rb new/lib/puma/capistrano.rb
--- old/lib/puma/capistrano.rb  2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/capistrano.rb  1970-01-01 01:00:00.000000000 +0100
@@ -1,94 +0,0 @@
-$stderr.puts "DEPRECATED: To manage puma with capistrano, use 
https://github.com/seuros/capistrano-puma";
-
-Capistrano::Configuration.instance.load do
-
-  # Ensure the tmp/sockets directory is created by the deploy:setup task and
-  # symlinked in by the deploy:update task. This is not handled by Capistrano
-  # v2 but is fixed in v3.
-  shared_children.push('tmp/sockets')
-
-  _cset(:puma_default_hooks)    { true }
-  _cset(:puma_cmd)    { "#{fetch(:bundle_cmd, 'bundle')} exec puma" }
-  _cset(:pumactl_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec pumactl" }
-  _cset(:puma_env)    { fetch(:rack_env, fetch(:rails_env, 'production')) }
-  _cset(:puma_state)  { "#{shared_path}/sockets/puma.state" }
-  _cset(:puma_socket) { "unix://#{shared_path}/sockets/puma.sock" }
-  _cset(:puma_role)   { :app }
-
-  if fetch(:puma_default_hooks)
-    after 'deploy:stop', 'puma:stop'
-    after 'deploy:start', 'puma:start'
-    after 'deploy:restart', 'puma:restart'
-  end
-
-  namespace :puma do
-    desc 'Start puma'
-    task :start, :roles => lambda { puma_role }, :on_no_matching_servers => 
:continue do
-      run "cd #{current_path} && #{puma_rails_additional_env} #{puma_cmd} 
#{start_options}", :pty => false
-    end
-
-    desc 'Stop puma'
-    task :stop, :roles => lambda { puma_role }, :on_no_matching_servers => 
:continue do
-      run "cd #{current_path} && #{pumactl_cmd} -S #{state_path} stop"
-    end
-
-    desc 'Restart puma'
-    task :restart, :roles => lambda { puma_role }, :on_no_matching_servers => 
:continue do
-      begin
-        run "cd #{current_path} && #{puma_rails_additional_env} #{pumactl_cmd} 
-S #{state_path} restart"
-      rescue Capistrano::CommandError => ex
-        puts "Failed to restart puma: #{ex}\nAssuming not started."
-        start
-      end
-    end
-
-    desc 'Restart puma (phased restart)'
-    task :phased_restart, :roles => lambda { puma_role }, 
:on_no_matching_servers => :continue do
-      begin
-        run "cd #{current_path} && #{puma_rails_additional_env} #{pumactl_cmd} 
-S #{state_path} phased-restart"
-      rescue Capistrano::CommandError => ex
-        puts "Failed to restart puma: #{ex}\nAssuming not started."
-        start
-      end
-    end
-
-  end
-
-  def start_options
-    if config_file
-      "-q -d -e #{puma_env} -C #{config_file}"
-    else
-      "-q -d -e #{puma_env} -b '#{puma_socket}' -S #{state_path} --control 
'unix://#{shared_path}/sockets/pumactl.sock'"
-    end
-  end
-
-  def config_file
-    @_config_file ||= begin
-      file = fetch(:puma_config_file, nil)
-      file = "./config/puma/#{puma_env}.rb" if !file && 
File.exists?("./config/puma/#{puma_env}.rb")
-      file
-    end
-  end
-
-  def puma_env
-    fetch(:rack_env, fetch(:rails_env, 'production'))
-  end
-
-  #add additional env when start rails, such as : secret key, db username, db 
pwd or other what you want.
-  def puma_rails_additional_env
-    fetch(:puma_rails_additional_env, '')
-  end
-
-  def state_path
-    (config_file ? configuration.options[:state] : nil) || puma_state
-  end
-
-  def configuration
-    require 'puma'
-    require 'puma/configuration'
-
-    config = Puma::Configuration.new(:config_file => config_file)
-    config.load
-    config
-  end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/cluster.rb new/lib/puma/cluster.rb
--- old/lib/puma/cluster.rb     2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/cluster.rb     2016-04-08 00:02:21.000000000 +0200
@@ -31,10 +31,9 @@
 
       # Be sure to change the directory again before loading
       # the app. This way we can pick up new code.
-      if dir = @options[:worker_directory]
-        log "+ Changing to #{dir}"
-        Dir.chdir dir
-      end
+      dir = @launcher.restart_dir
+      log "+ Changing to #{dir}"
+      Dir.chdir dir
     end
 
     def redirect_io
@@ -119,6 +118,12 @@
         @launcher.config.run_hooks :before_worker_fork, idx
 
         pid = fork { worker(idx, master) }
+        if !pid
+          log "! Complete inability to spawn new workers detected"
+          log "! Seppuku is the only choice."
+          exit! 1
+        end
+
         debug "Spawned worker: #{pid}"
         @workers << Worker.new(idx, pid, @phase, @options)
 
@@ -219,8 +224,12 @@
 
       # If we're not running under a Bundler context, then
       # report the info about the context we will be using
-      if !ENV['BUNDLE_GEMFILE'] and File.exist?("Gemfile")
-        log "+ Gemfile in context: #{File.expand_path("Gemfile")}"
+      if !ENV['BUNDLE_GEMFILE']
+        if File.exist?("Gemfile")
+          log "+ Gemfile in context: #{File.expand_path("Gemfile")}"
+        elsif File.exist?("gems.rb")
+          log "+ Gemfile in context: #{File.expand_path("gems.rb")}"
+        end
       end
 
       # Invoke any worker boot hooks so they can get
@@ -298,10 +307,9 @@
     end
 
     def reload_worker_directory
-      if dir = @options[:worker_directory]
-        log "+ Changing to #{dir}"
-        Dir.chdir dir
-      end
+      dir = @launcher.restart_dir
+      log "+ Changing to #{dir}"
+      Dir.chdir dir
     end
 
     def stats
@@ -422,12 +430,21 @@
       @launcher.events.fire_on_booted!
 
       begin
+        force_check = false
+
         while @status == :run
           begin
-            res = IO.select([read], nil, nil, 5)
+            if @phased_restart
+              start_phased_restart
+              @phased_restart = false
+            end
+
+            check_workers force_check
 
             force_check = false
 
+            res = IO.select([read], nil, nil, 5)
+
             if res
               req = read.read_nonblock(1)
 
@@ -453,13 +470,6 @@
               end
             end
 
-            if @phased_restart
-              start_phased_restart
-              @phased_restart = false
-            end
-
-            check_workers force_check
-
           rescue Interrupt
             @status = :stop
           end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/configuration.rb 
new/lib/puma/configuration.rb
--- old/lib/puma/configuration.rb       2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/configuration.rb       2016-04-08 00:02:21.000000000 +0200
@@ -13,10 +13,10 @@
   end
 
   class LeveledOptions
-    def initialize(default={})
-      @cur = {}
+    def initialize(default_options, user_options)
+      @cur = user_options
       @set = [@cur]
-      @defaults = default.dup
+      @defaults = default_options.dup
     end
 
     def initialize_copy(other)
@@ -133,12 +133,9 @@
     end
 
     def initialize(options={}, &blk)
-      @options = LeveledOptions.new(default_options)
-      @plugins = PluginLoader.new
+      @options = LeveledOptions.new(default_options, options)
 
-      # options.each do |k,v|
-        # @options[k] = v
-      # end
+      @plugins = PluginLoader.new
 
       if blk
         configure(&blk)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/const.rb new/lib/puma/const.rb
--- old/lib/puma/const.rb       2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/const.rb       2016-04-08 00:02:21.000000000 +0200
@@ -100,8 +100,8 @@
   # too taxing on performance.
   module Const
 
-    PUMA_VERSION = VERSION = "3.1.1".freeze
-    CODE_NAME = "El Niño Winter Wonderland".freeze
+    PUMA_VERSION = VERSION = "3.4.0".freeze
+    CODE_NAME = "Owl Bowl Brawl".freeze
     PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
     
     FAST_TRACK_KA_TIMEOUT = 0.2
@@ -118,6 +118,11 @@
     # sending data back
     WRITE_TIMEOUT = 10
 
+    # How long, after raising the ForceShutdown of a thread during
+    # forced shutdown mode, to wait for the thread to try and finish
+    # up it's work before leaving the thread to die on the vine.
+    SHUTDOWN_GRACE_TIME = 5 # seconds
+
     DATE = "Date".freeze
 
     SCRIPT_NAME = "SCRIPT_NAME".freeze
@@ -125,6 +130,7 @@
     # The original URI requested by the client.
     REQUEST_URI= 'REQUEST_URI'.freeze
     REQUEST_PATH = 'REQUEST_PATH'.freeze
+    QUERY_STRING = 'QUERY_STRING'.freeze
 
     PATH_INFO = 'PATH_INFO'.freeze
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/dsl.rb new/lib/puma/dsl.rb
--- old/lib/puma/dsl.rb 2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/dsl.rb 2016-04-08 00:02:21.000000000 +0200
@@ -159,6 +159,26 @@
       @options[:environment] = environment
     end
 
+    # How long to wait for threads to stop when shutting them
+    # down. Defaults to :forever. Specifying :immediately will cause
+    # Puma to kill the threads immediately.  Otherwise the value
+    # is the number of seconds to wait.
+    #
+    # Puma always waits a few seconds after killing a thread for it to try
+    # to finish up it's work, even in :immediately mode.
+    def force_shutdown_after(val=:forever)
+      i = case val
+          when :forever
+            -1
+          when :immediately
+            0
+          else
+            Integer(val)
+          end
+
+      @options[:force_shutdown_after] = i
+    end
+
     # Code to run before doing a restart. This code should
     # close logfiles, database connections, etc.
     #
@@ -271,6 +291,15 @@
       _ary(:before_fork) << block
     end
 
+    # *Cluster mode only* Code to run in a worker when it boots to setup
+    # the process before booting the app.
+    #
+    # This can be called multiple times to add hooks.
+    #
+    def on_worker_boot(&block)
+      _ary(:before_worker_boot) << block
+    end
+
     # *Cluster mode only* Code to run immediately before a worker shuts
     # down (after it has finished processing HTTP requests). These hooks
     # can block if necessary to wait for background operations unknown
@@ -282,16 +311,7 @@
       _ary(:before_worker_shutdown) << block
     end
 
-    # *Cluster mode only* Code to run when a worker boots to setup
-    # the process before booting the app.
-    #
-    # This can be called multiple times to add hooks.
-    #
-    def on_worker_boot(&block)
-      _ary(:before_worker_boot) << block
-    end
-
-    # *Cluster mode only* Code to run when a master process is
+    # *Cluster mode only* Code to run in the master when it is
     # about to create the worker by forking itself.
     #
     # This can be called multiple times to add hooks.
@@ -300,25 +320,26 @@
       _ary(:before_worker_fork) << block
     end
 
-    # *Cluster mode only* Code to run when a worker boots to setup
-    # the process after booting the app.
+    # *Cluster mode only* Code to run in the master after it starts
+    # a worker.
     #
     # This can be called multiple times to add hooks.
     #
-    def after_worker_boot(&block)
+    def after_worker_fork(&block)
       _ary(:after_worker_fork) << block
     end
 
+    alias_method :after_worker_boot, :after_worker_fork
+
     # The directory to operate out of.
     def directory(dir)
       @options[:directory] = dir.to_s
-
-      worker_directory dir
     end
 
-    # Set the directory for workers to start in
+    # DEPRECATED: The directory to operate out of.
     def worker_directory(dir)
-      @options[:worker_directory] = dir.to_s
+      $stderr.puts "worker_directory is deprecated. Please use `directory`"
+      directory dir
     end
 
     # Run the app as a raw TCP app instead of an HTTP rack app
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/launcher.rb new/lib/puma/launcher.rb
--- old/lib/puma/launcher.rb    2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/launcher.rb    2016-04-08 00:02:21.000000000 +0200
@@ -12,7 +12,7 @@
 require 'puma/commonlogger'
 
 module Puma
-  # Puam::Launcher is the single entry point for starting a Puma server based 
on user
+  # Puma::Launcher is the single entry point for starting a Puma server based 
on user
   # configuration. It is responsible for taking user supplied arguments and 
resolving them
   # with configuration in `config/puma.rb` or `config/puma/<env>.rb`.
   #
@@ -54,8 +54,6 @@
       @binder        = Binder.new(@events)
       @binder.import_from_env
 
-      generate_restart_data
-
       @environment = conf.environment
 
       # Advertise the Configuration
@@ -65,6 +63,8 @@
 
       @options = @config.options
 
+      generate_restart_data
+
       if clustered? && (Puma.jruby? || Puma.windows?)
         unsupported 'worker mode not supported on JRuby or Windows'
       end
@@ -73,8 +73,7 @@
         unsupported 'daemon mode not supported on Windows'
       end
 
-      dir = @options[:directory]
-      Dir.chdir(dir) if dir
+      Dir.chdir(@restart_dir)
 
       prune_bundler if prune_bundler?
 
@@ -93,7 +92,7 @@
       @status = :run
     end
 
-    attr_reader :binder, :events, :config, :options
+    attr_reader :binder, :events, :config, :options, :restart_dir
 
     # Return stats about the server
     def stats
@@ -314,16 +313,18 @@
 
 
     def generate_restart_data
-      # Use the same trick as unicorn, namely favor PWD because
-      # it will contain an unresolved symlink, useful for when
-      # the pwd is /data/releases/current.
-      if dir = ENV['PWD']
+      if dir = @options[:directory]
+        @restart_dir = dir
+
+        # Use the same trick as unicorn, namely favor PWD because
+        # it will contain an unresolved symlink, useful for when
+        # the pwd is /data/releases/current.
+      elsif dir = ENV['PWD']
         s_env = File.stat(dir)
         s_pwd = File.stat(Dir.pwd)
 
         if s_env.ino == s_pwd.ino and (Puma.jruby? or s_env.dev == s_pwd.dev)
           @restart_dir = dir
-          @config.configure { |c| c.worker_directory dir }
         end
       end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/rack/backports/uri/common_18.rb 
new/lib/puma/rack/backports/uri/common_18.rb
--- old/lib/puma/rack/backports/uri/common_18.rb        2016-03-18 
05:32:21.000000000 +0100
+++ new/lib/puma/rack/backports/uri/common_18.rb        2016-04-08 
00:02:21.000000000 +0200
@@ -7,22 +7,25 @@
 #
 
 module URI
-  TBLENCWWWCOMP_ = {} # :nodoc:
-  256.times do |i|
-    TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
+  begin
+    TBLENCWWWCOMP_ = {} # :nodoc:
+    256.times do |i|
+      TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
+    end
+    TBLENCWWWCOMP_[' '] = '+'
+    TBLENCWWWCOMP_.freeze
+    TBLDECWWWCOMP_ = {} # :nodoc:
+    256.times do |i|
+      h, l = i>>4, i&15
+      TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
+      TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
+      TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
+      TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+    end
+    TBLDECWWWCOMP_['+'] = ' '
+    TBLDECWWWCOMP_.freeze
+  rescue Exception
   end
-  TBLENCWWWCOMP_[' '] = '+'
-  TBLENCWWWCOMP_.freeze
-  TBLDECWWWCOMP_ = {} # :nodoc:
-  256.times do |i|
-    h, l = i>>4, i&15
-    TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
-    TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
-    TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
-    TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
-  end
-  TBLDECWWWCOMP_['+'] = ' '
-  TBLDECWWWCOMP_.freeze
 
   # Encode given +s+ to URL-encoded form data.
   #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/rack/backports/uri/common_192.rb 
new/lib/puma/rack/backports/uri/common_192.rb
--- old/lib/puma/rack/backports/uri/common_192.rb       2016-03-18 
05:32:21.000000000 +0100
+++ new/lib/puma/rack/backports/uri/common_192.rb       2016-04-08 
00:02:21.000000000 +0200
@@ -17,17 +17,20 @@
 require 'uri/common'
 
 module URI
-  TBLDECWWWCOMP_ = {} unless const_defined?(:TBLDECWWWCOMP_)  #:nodoc:
-  if TBLDECWWWCOMP_.empty?
-    256.times do |i|
-      h, l = i>>4, i&15
-      TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
-      TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
-      TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
-      TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+  begin
+    TBLDECWWWCOMP_ = {} unless const_defined?(:TBLDECWWWCOMP_)  #:nodoc:
+    if TBLDECWWWCOMP_.empty?
+      256.times do |i|
+        h, l = i>>4, i&15
+        TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+      end
+      TBLDECWWWCOMP_['+'] = ' '
+      TBLDECWWWCOMP_.freeze
     end
-    TBLDECWWWCOMP_['+'] = ' '
-    TBLDECWWWCOMP_.freeze
+  rescue Exception
   end
 
   def self.decode_www_form(str, enc=Encoding::UTF_8)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/rack/backports/uri/common_193.rb 
new/lib/puma/rack/backports/uri/common_193.rb
--- old/lib/puma/rack/backports/uri/common_193.rb       2016-03-18 
05:32:21.000000000 +0100
+++ new/lib/puma/rack/backports/uri/common_193.rb       2016-04-08 
00:02:21.000000000 +0200
@@ -8,22 +8,26 @@
 # Relevant commit:
 # https://github.com/ruby/ruby/commit/edb7cdf1eabaff78dfa5ffedfbc2e91b29fa9ca1
 
+
 module URI
-  256.times do |i|
-    TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
-  end
-  TBLENCWWWCOMP_[' '] = '+'
-  TBLENCWWWCOMP_.freeze
+  begin
+    256.times do |i|
+      TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
+    end
+    TBLENCWWWCOMP_[' '] = '+'
+    TBLENCWWWCOMP_.freeze
 
-  256.times do |i|
-    h, l = i>>4, i&15
-    TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
-    TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
-    TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
-    TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+    256.times do |i|
+      h, l = i>>4, i&15
+      TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
+      TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
+      TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
+      TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+    end
+    TBLDECWWWCOMP_['+'] = ' '
+    TBLDECWWWCOMP_.freeze
+  rescue Exception
   end
-  TBLDECWWWCOMP_['+'] = ' '
-  TBLDECWWWCOMP_.freeze
 end
 
 # :startdoc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/reactor.rb new/lib/puma/reactor.rb
--- old/lib/puma/reactor.rb     2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/reactor.rb     2016-04-08 00:02:21.000000000 +0200
@@ -77,6 +77,8 @@
 
               # SSL handshake failure
               rescue MiniSSL::SSLError => e
+                @server.lowlevel_error(e, c.env)
+
                 ssl_socket = c.io
                 addr = ssl_socket.peeraddr.last
                 cert = ssl_socket.peercert
@@ -88,6 +90,8 @@
 
               # The client doesn't know HTTP well
               rescue HttpParserError => e
+                @server.lowlevel_error(e, c.env)
+
                 c.write_400
                 c.close
 
@@ -95,6 +99,8 @@
 
                 @events.parse_error @server, c.env, e
               rescue StandardError => e
+                @server.lowlevel_error(e, c.env)
+
                 c.write_500
                 c.close
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/server.rb new/lib/puma/server.rb
--- old/lib/puma/server.rb      2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/server.rb      2016-04-08 00:02:21.000000000 +0200
@@ -430,6 +430,8 @@
 
       # SSL handshake error
       rescue MiniSSL::SSLError => e
+        lowlevel_error(e, client.env)
+
         ssl_socket = client.io
         addr = ssl_socket.peeraddr.last
         cert = ssl_socket.peercert
@@ -440,12 +442,16 @@
 
       # The client doesn't know HTTP well
       rescue HttpParserError => e
+        lowlevel_error(e, client.env)
+
         client.write_400
 
         @events.parse_error self, client.env, e
 
       # Server error
       rescue StandardError => e
+        lowlevel_error(e, client.env)
+
         client.write_500
 
         @events.unknown_error self, e, "Read"
@@ -486,6 +492,8 @@
         env[REQUEST_PATH] = uri.path
 
         raise "No REQUEST PATH" unless env[REQUEST_PATH]
+
+        env[QUERY_STRING] = uri.query
       end
 
       env[PATH_INFO] = env[REQUEST_PATH]
@@ -571,6 +579,14 @@
 
             return :async
           end
+        rescue ThreadPool::ForceShutdown => e
+          @events.log "Detected force shutdown of a thread, returning 503"
+          @events.unknown_error self, e, "Rack app"
+
+          status = 503
+          headers = {}
+          res_body = ["Request was internally terminated early\n"]
+
         rescue StandardError => e
           @events.unknown_error self, e, "Rack app"
 
@@ -723,7 +739,7 @@
     end
     private :fetch_status_code
 
-    # Given the requset +env+ from +client+ and the partial body +body+
+    # Given the request +env+ from +client+ and the partial body +body+
     # plus a potential Content-Length value +cl+, finish reading
     # the body and return it.
     #
@@ -835,7 +851,13 @@
         @events.debug "Drained #{count} additional connections."
       end
 
-      @thread_pool.shutdown if @thread_pool
+      if @thread_pool
+        if timeout = @options[:force_shutdown_after]
+          @thread_pool.shutdown timeout.to_i
+        else
+          @thread_pool.shutdown
+        end
+      end
     end
 
     # Stops the acceptor thread and then causes the worker threads to finish
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/single.rb new/lib/puma/single.rb
--- old/lib/puma/single.rb      2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/single.rb      2016-04-08 00:02:21.000000000 +0200
@@ -71,7 +71,7 @@
             exit 1
           end
 
-          pid = jruby_daemon_start
+          jruby_daemon_start
           sleep
         end
       else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/puma/thread_pool.rb new/lib/puma/thread_pool.rb
--- old/lib/puma/thread_pool.rb 2016-03-18 05:32:21.000000000 +0100
+++ new/lib/puma/thread_pool.rb 2016-04-08 00:02:21.000000000 +0200
@@ -5,6 +5,9 @@
   #
   class ThreadPool
 
+    class ForceShutdown < RuntimeError
+    end
+
     # Maintain a minimum of +min+ and maximum of +max+ threads
     # in the pool.
     #
@@ -239,7 +242,7 @@
 
     # Tell all threads in the pool to exit and wait for them to finish.
     #
-    def shutdown
+    def shutdown(timeout=-1)
       threads = @mutex.synchronize do
         @shutdown = true
         @not_empty.broadcast
@@ -251,7 +254,38 @@
         @workers.dup
       end
 
-      threads.each(&:join)
+      case timeout
+      when -1
+        threads.each(&:join)
+      when 0
+        threads.each do |t|
+          t.raise ForceShutdown
+        end
+
+        threads.each do |t|
+          t.join Const::SHUTDOWN_GRACE_TIME
+        end
+      else
+        timeout.times do
+          threads.delete_if do |t|
+            t.join 1
+          end
+
+          if threads.empty?
+            break
+          else
+            sleep 1
+          end
+        end
+
+        threads.each do |t|
+          t.raise ForceShutdown
+        end
+
+        threads.each do |t|
+          t.join Const::SHUTDOWN_GRACE_TIME
+        end
+      end
 
       @spawned = 0
       @workers = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rack/handler/puma.rb new/lib/rack/handler/puma.rb
--- old/lib/rack/handler/puma.rb        2016-03-18 05:32:21.000000000 +0100
+++ new/lib/rack/handler/puma.rb        2016-04-08 00:02:21.000000000 +0200
@@ -12,7 +12,7 @@
       def self.run(app, options = {})
         options  = DEFAULT_OPTIONS.merge(options)
 
-        conf = ::Puma::Configuration.new do |c|
+        conf = ::Puma::Configuration.new(options) do |c|
           c.quiet
 
           if options.delete(:Verbose)
@@ -69,4 +69,3 @@
     register :puma, Puma
   end
 end
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2016-03-18 05:32:21.000000000 +0100
+++ new/metadata        2016-04-08 00:02:21.000000000 +0200
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: puma
 version: !ruby/object:Gem::Version
-  version: 3.1.1
+  version: 3.4.0
 platform: ruby
 authors:
 - Evan Phoenix
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2016-03-18 00:00:00.000000000 Z
+date: 2016-04-07 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rdoc
@@ -64,14 +64,14 @@
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '3.14'
+        version: '3.15'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '3.14'
+        version: '3.15'
 description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 
server
   for Ruby/Rack applications. Puma is intended for use in both development and 
production
   environments. In order to get the best throughput, it is highly recommended 
that
@@ -91,6 +91,7 @@
 - docs/config.md
 - docs/nginx.md
 - docs/signals.md
+- docs/systemd.md
 - tools/jungle/README.md
 - tools/jungle/init.d/README.md
 - tools/jungle/upstart/README.md
@@ -108,6 +109,7 @@
 - docs/config.md
 - docs/nginx.md
 - docs/signals.md
+- docs/systemd.md
 - ext/puma_http11/PumaHttp11Service.java
 - ext/puma_http11/ext_help.h
 - ext/puma_http11/extconf.rb
@@ -126,7 +128,6 @@
 - lib/puma/accept_nonblock.rb
 - lib/puma/app/status.rb
 - lib/puma/binder.rb
-- lib/puma/capistrano.rb
 - lib/puma/cli.rb
 - lib/puma/client.rb
 - lib/puma/cluster.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tools/jungle/init.d/puma new/tools/jungle/init.d/puma
--- old/tools/jungle/init.d/puma        2016-03-18 05:32:21.000000000 +0100
+++ new/tools/jungle/init.d/puma        2016-04-08 00:02:21.000000000 +0200
@@ -357,7 +357,7 @@
   ;;
   add)
     if [ "$#" -lt 3 ]; then
-      echo "Please, specifiy the app's directory and the user that will run it 
at least."
+      echo "Please, specify the app's directory and the user that will run it 
at least."
       echo "  Usage: $SCRIPTNAME add /path/to/app user 
/path/to/app/config/puma.rb /path/to/app/config/log/puma.log"
       echo "    config and log are optionals."
       exit 1


Reply via email to