diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index 0160476b..0cf3c952 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -47,6 +47,7 @@ class Arbiter(object): def __init__(self, address, num_workers, app, **kwargs): self.address = address self.num_workers = num_workers + self.worker_age = 0 self.app = app self.timeout = 30 @@ -238,10 +239,11 @@ class Arbiter(object): def handle_ttou(self): """ SIGTTOU handling. Decrease number of workers.""" - if self.num_workers > 0: - self.num_workers -= 1 + if self.num_workers <= 1: + return + self.num_workers -= 1 self.manage_workers() - + def handle_usr1(self): """ SIGUSR1 handling. send USR1 to workers (which will kill it)""" self.kill_workers(signal.SIGUSR1) @@ -348,9 +350,13 @@ class Arbiter(object): if len(self.WORKERS.keys()) < self.num_workers: self.spawn_workers() - for pid, w in self.WORKERS.items(): - if w.id >= self.num_workers: - self.kill_worker(pid, signal.SIGQUIT) + num_to_kill = len(self.WORKERS) - self.num_workers + for i in range(num_to_kill, 0, -1): + 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): """ spawn new workers """ @@ -359,7 +365,9 @@ class Arbiter(object): if i in workers: 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.conf.before_fork(self, worker) pid = os.fork() diff --git a/gunicorn/worker.py b/gunicorn/worker.py index 4d128739..41ed6982 100644 --- a/gunicorn/worker.py +++ b/gunicorn/worker.py @@ -27,9 +27,10 @@ class Worker(object): PIPE = [] - def __init__(self, workerid, ppid, socket, app, timeout, conf): + def __init__(self, workerid, age, ppid, socket, app, timeout, conf): self.nr = 0 self.id = workerid + self.age = age self.ppid = ppid self.debug = conf['debug'] self.conf = conf