integ/python/python-gunicorn/centos/patches/0001-add-worker-abort-hook....

93 lines
2.9 KiB
Diff

From d78a84dc692f708afd90df3409f9e264c22231dd Mon Sep 17 00:00:00 2001
From: Giao Le <giao.le@windriver.com>
Date: Tue, 22 Nov 2016 10:18:14 -0500
Subject: [PATCH 1/1] add worker abort hook
---
gunicorn/arbiter.py | 9 +++++++--
gunicorn/config.py | 18 ++++++++++++++++++
gunicorn/workers/base.py | 7 +++++++
3 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py
index b48e5b7..4d2daad 100644
--- a/gunicorn/arbiter.py
+++ b/gunicorn/arbiter.py
@@ -429,8 +429,13 @@ class Arbiter(object):
except ValueError:
continue
- self.log.critical("WORKER TIMEOUT (pid:%s)", pid)
- self.kill_worker(pid, signal.SIGKILL)
+ if not worker.aborted:
+ self.log.critical("WORKER TIMEOUT (pid:%s)", pid)
+ worker.aborted = True
+ self.kill_worker(pid, signal.SIGABRT)
+ else:
+ self.kill_worker(pid, signal.SIGKILL)
+
def reap_workers(self):
"""\
diff --git a/gunicorn/config.py b/gunicorn/config.py
index efcc449..3aec7ae 100644
--- a/gunicorn/config.py
+++ b/gunicorn/config.py
@@ -1282,6 +1282,24 @@ class PostWorkerInit(Setting):
"""
+class WorkerAbort(Setting):
+ name = "worker_abort"
+ section = "Server Hooks"
+ validator = validate_callable(1)
+ type = six.callable
+
+ def worker_abort(worker):
+ pass
+
+ default = staticmethod(worker_abort)
+ desc = """\
+ Called when a worker received the SIGABRT signal.
+ This call generally happens on timeout.
+ The callable needs to accept one instance variable for the initialized
+ Worker.
+ """
+
+
class PreExec(Setting):
name = "pre_exec"
section = "Server Hooks"
diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py
index 5566dd1..af785a1 100644
--- a/gunicorn/workers/base.py
+++ b/gunicorn/workers/base.py
@@ -40,6 +40,7 @@ class Worker(object):
self.timeout = timeout
self.cfg = cfg
self.booted = False
+ self.aborted = False
self.nr = 0
self.max_requests = cfg.max_requests or MAXSIZE
@@ -120,6 +121,7 @@ class Worker(object):
signal.signal(signal.SIGINT, self.handle_exit)
signal.signal(signal.SIGWINCH, self.handle_winch)
signal.signal(signal.SIGUSR1, self.handle_usr1)
+ signal.signal(signal.SIGABRT, self.handle_abort)
# Don't let SIGQUIT and SIGUSR1 disturb active requests
# by interrupting system calls
if hasattr(signal, 'siginterrupt'): # python >= 2.6
@@ -202,3 +204,8 @@ class Worker(object):
def handle_winch(self, sig, fname):
# Ignore SIGWINCH in worker. Fixes a crash on OpenBSD.
return
+
+ def handle_abort(self, sig, frame):
+ self.alive = False
+ self.cfg.worker_abort(self)
+ sys.exit(1)
--
1.8.3.1