mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
New on_reload server hook to customize how SIGHUPs spawn new workers.
This commit is contained in:
parent
4879005cc1
commit
d6560726c5
@ -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>
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user