New on_reload server hook to customize how SIGHUPs spawn new workers.

This commit is contained in:
Phil Schanely 2011-08-04 13:04:50 -04:00 committed by benoitc
parent 4879005cc1
commit d6560726c5
4 changed files with 39 additions and 8 deletions

View File

@ -448,6 +448,21 @@ def start_server(server):
<p>Called just after the server is started.</p>
<p>The callable needs to accept a single instance variable for the Arbiter.</p>
</div>
<div class="section" id="on-reload">
<h4><a class="toc-backref" href="#contents">on_reload</a></h4>
<ul>
<li><pre class="first literal-block">
def on_reload(server):
for i in range(server.app.cfg.workers):
server.spawn_worker()
</pre>
</li>
</ul>
<p>Called during a reload from a SIGHUP signal.
This callback should create an appropriate number of new workers.
Old workers will be killed automatically by gunicorn, so it is not required to do so here.</p>
<p>The callable needs to accept a single instance variable for the Arbiter.</p>
</div>
<div class="section" id="pre-fork">
<h4><a class="toc-backref" href="#contents">pre_fork</a></h4>
<ul>

View File

@ -337,17 +337,17 @@ class Arbiter(object):
"""
if self.pidfile is not None:
self.pidfile.rename("%s.oldbin" % self.pidfile.fname)
self.reexec_pid = os.fork()
if self.reexec_pid != 0:
self.master_name = "Old Master"
return
os.environ['GUNICORN_FD'] = str(self.LISTENER.fileno())
os.chdir(self.START_CTX['cwd'])
self.cfg.pre_exec(self)
os.execvpe(self.START_CTX[0], self.START_CTX['args'], os.environ)
def reload(self):
old_address = self.cfg.address
@ -362,8 +362,7 @@ class Arbiter(object):
self.log.info("Listening at: %s", self.LISTENER)
# spawn new workers with new app & conf
for i in range(self.app.cfg.workers):
self.spawn_worker()
self.cfg.on_reload(self)
# unlink pidfile
if self.pidfile is not None:
@ -388,8 +387,7 @@ class Arbiter(object):
"""
for (pid, worker) in self.WORKERS.items():
try:
diff = time.time() - os.fstat(worker.tmp.fileno()).st_ctime
if diff <= self.timeout:
if time.time() - worker.tmp.last_update() <= self.timeout:
continue
except ValueError:
continue
@ -446,7 +444,7 @@ class Arbiter(object):
pid = os.fork()
if pid != 0:
self.WORKERS[pid] = worker
return
return pid
# Process Child
worker_pid = os.getpid()

View File

@ -637,6 +637,21 @@ class OnStarting(Setting):
The callable needs to accept a single instance variable for the Arbiter.
"""
class OnReload(Setting):
name = "on_reload"
section = "Server Hooks"
validator = validate_callable(1)
type = "callable"
def on_reload(server):
for i in range(server.app.cfg.workers):
server.spawn_worker()
default = staticmethod(on_reload)
desc = """\
Called to recycle workers during a reload via SIGHUP.
The callable needs to accept a single instance variable for the Arbiter.
"""
class WhenReady(Setting):
name = "when_ready"
section = "Server Hooks"

View File

@ -37,6 +37,9 @@ class WorkerTmp(object):
self._tmp.truncate(0)
os.write(self._tmp.fileno(), "X")
def last_update(self):
return os.fstat(self._tmp.fileno()).st_ctime
def fileno(self):
return self._tmp.fileno()