3cd12006bb
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
93 lines
2.9 KiB
Diff
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
|
|
|