Merge branch 'feature/nonReplacingSignalHandlers' of https://github.com/alexeevit/puma into alexeevit-feature/nonReplacingSignalHandlers

This commit is contained in:
Nate Berkopec 2022-04-17 09:18:10 -07:00
commit 32a2915999
No known key found for this signature in database
GPG Key ID: 19616755F4328D71
4 changed files with 66 additions and 18 deletions

View File

@ -5,6 +5,7 @@ require 'puma/util'
require 'puma/plugin'
require 'puma/cluster/worker_handle'
require 'puma/cluster/worker'
require 'puma/signal'
require 'time'
@ -288,7 +289,7 @@ module Puma
# of the signals handlers as small as possible.
def setup_signals
if @options[:fork_worker]
Signal.trap "SIGURG" do
Puma::Signal.trap "SIGURG" do
fork_worker!
end
@ -302,23 +303,23 @@ module Puma
end
end
Signal.trap "SIGCHLD" do
Puma::Signal.trap "SIGCHLD" do
wakeup!
end
Signal.trap "TTIN" do
Puma::Signal.trap "TTIN" do
@options[:workers] += 1
wakeup!
end
Signal.trap "TTOU" do
Puma::Signal.trap "TTOU" do
@options[:workers] -= 1 if @options[:workers] >= 2
wakeup!
end
master_pid = Process.pid
Signal.trap "SIGTERM" do
Puma::Signal.trap "SIGTERM" do
# The worker installs their own SIGTERM when booted.
# Until then, this is run by the worker and the worker
# should just exit if they get it.
@ -418,7 +419,7 @@ module Puma
spawn_workers
Signal.trap "SIGINT" do
Puma::Signal.trap "SIGINT" do
stop
end

View File

@ -30,8 +30,12 @@ module Puma
title += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
$0 = title
Signal.trap "SIGINT", "IGNORE"
Signal.trap "SIGCHLD", "DEFAULT"
Puma::Signal.trap "SIGINT" do
end
Puma::Signal.trap "SIGCHLD" do |signal|
raise SignalException, signal
end
Thread.new do
Puma.set_thread_name "wrkr check"
@ -55,7 +59,7 @@ module Puma
@launcher.config.run_hooks(:before_worker_boot, index, @launcher.log_writer)
begin
server = @server ||= start_server
server = @server ||= start_server
rescue Exception => e
log "! Unable to start worker"
log e.backtrace[0]
@ -69,7 +73,7 @@ module Puma
if fork_worker
restart_server.clear
worker_pids = []
Signal.trap "SIGCHLD" do
Puma::Signal.trap "SIGCHLD" do
wakeup! if worker_pids.reject! do |p|
Process.wait(p, Process::WNOHANG) rescue true
end
@ -96,7 +100,7 @@ module Puma
end
end
Signal.trap "SIGTERM" do
Puma::Signal.trap "SIGTERM" do
@worker_write << "e#{Process.pid}\n" rescue nil
restart_server.clear
server.stop

View File

@ -8,6 +8,7 @@ require 'puma/single'
require 'puma/const'
require 'puma/binder'
require 'puma/launcher/bundle_pruner'
require 'puma/signal'
module Puma
# Puma::Launcher is the single entry point for starting a Puma server based on user
@ -414,7 +415,7 @@ module Puma
def setup_signals
begin
Signal.trap "SIGUSR2" do
Puma::Signal.trap "SIGUSR2" do
restart
end
rescue Exception
@ -423,7 +424,7 @@ module Puma
unless Puma.jruby?
begin
Signal.trap "SIGUSR1" do
Puma::Signal.trap "SIGUSR1" do
phased_restart
end
rescue Exception
@ -432,9 +433,9 @@ module Puma
end
begin
Signal.trap "SIGTERM" do
Puma::Signal.trap "SIGTERM" do
# Shortcut the control flow in case raise_exception_on_sigterm is true
do_graceful_stop
graceful_stop
raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm]
end
@ -443,7 +444,7 @@ module Puma
end
begin
Signal.trap "SIGINT" do
Puma::Signal.trap "SIGINT" do
stop
end
rescue Exception
@ -451,7 +452,7 @@ module Puma
end
begin
Signal.trap "SIGHUP" do
Puma::Signal.trap "SIGHUP" do
if @runner.redirected_io?
@runner.redirect_io
else
@ -464,7 +465,7 @@ module Puma
begin
unless Puma.jruby? # INFO in use by JVM already
Signal.trap "SIGINFO" do
Puma::Signal.trap "SIGINFO" do
thread_status do |name, backtrace|
@log_writer.log(name)
@log_writer.log(backtrace.map { |bt| " #{bt}" })

42
lib/puma/signal.rb Normal file
View File

@ -0,0 +1,42 @@
module Puma
module Signal
module_function
def prepend_handler(sig, &handler)
name = signame(sig)
custom_signal_handlers[signame] ||= []
custom_signal_handlers[signame].prepend(handler)
end
# Signal.trap that does not replace
# the existing puma handlers
def trap(sig, &handler)
name = signame(sig)
::Signal.trap(name) do
invoke_custom_signal_handlers(name)
yield handler
end
end
private
def signame(sig)
name = sig.is_a?(Integer) ? ::Signal.signame(sig) : String(sig).sub('SIG', '')
raise ArgumentError, "unsupported signal SIG#{name}" unless ::Signal.list[name]
name
end
module_function :signame
def invoke_custom_signal_handlers(signame)
Array(custom_signal_handlers[signame]).each do |handler|
yield handler
end
end
module_function :invoke_custom_signal_handlers
def custom_signal_handlers
@custom_signal_handlers ||= {}
end
module_function :custom_signal_handlers
end
end