Fixes Issue #9 - Recycle oldest workers first.

The worker that's been alive the longest will now be the first
worker to be recycled when the master process receives a TTOU
signal.
This commit is contained in:
Paul J. Davis 2010-02-27 00:46:31 -05:00
parent fd059eaf8f
commit 1e1207418f
2 changed files with 17 additions and 8 deletions

View File

@ -47,6 +47,7 @@ class Arbiter(object):
def __init__(self, address, num_workers, app, **kwargs): def __init__(self, address, num_workers, app, **kwargs):
self.address = address self.address = address
self.num_workers = num_workers self.num_workers = num_workers
self.worker_age = 0
self.app = app self.app = app
self.timeout = 30 self.timeout = 30
@ -238,8 +239,9 @@ class Arbiter(object):
def handle_ttou(self): def handle_ttou(self):
""" SIGTTOU handling. Decrease number of workers.""" """ SIGTTOU handling. Decrease number of workers."""
if self.num_workers > 0: if self.num_workers <= 1:
self.num_workers -= 1 return
self.num_workers -= 1
self.manage_workers() self.manage_workers()
def handle_usr1(self): def handle_usr1(self):
@ -348,9 +350,13 @@ class Arbiter(object):
if len(self.WORKERS.keys()) < self.num_workers: if len(self.WORKERS.keys()) < self.num_workers:
self.spawn_workers() self.spawn_workers()
for pid, w in self.WORKERS.items(): num_to_kill = len(self.WORKERS) - self.num_workers
if w.id >= self.num_workers: for i in range(num_to_kill, 0, -1):
self.kill_worker(pid, signal.SIGQUIT) pid, age = 0, sys.maxint
for (wpid, worker) in self.WORKERS.iteritems():
if worker.age < age:
pid, age = wpid, worker.age
self.kill_worker(pid, signal.SIGQUIT)
def spawn_workers(self): def spawn_workers(self):
""" spawn new workers """ """ spawn new workers """
@ -359,7 +365,9 @@ class Arbiter(object):
if i in workers: if i in workers:
continue continue
worker = Worker(i, self.pid, self.LISTENER, self.app, self.worker_age += 1
worker = Worker(i, self.worker_age, self.pid,
self.LISTENER, self.app,
self.timeout/2.0, self.conf) self.timeout/2.0, self.conf)
self.conf.before_fork(self, worker) self.conf.before_fork(self, worker)
pid = os.fork() pid = os.fork()

View File

@ -27,9 +27,10 @@ class Worker(object):
PIPE = [] PIPE = []
def __init__(self, workerid, ppid, socket, app, timeout, conf): def __init__(self, workerid, age, ppid, socket, app, timeout, conf):
self.nr = 0 self.nr = 0
self.id = workerid self.id = workerid
self.age = age
self.ppid = ppid self.ppid = ppid
self.debug = conf['debug'] self.debug = conf['debug']
self.conf = conf self.conf = conf