some fixes

This commit is contained in:
Benoit Chesneau 2009-12-02 01:12:35 +01:00
parent d63890c77a
commit b9468919e6
3 changed files with 55 additions and 28 deletions

View File

@ -82,7 +82,7 @@ class HTTPServer(object):
self.LISTENERS.append(sock) self.LISTENERS.append(sock)
except socket.error, e: except socket.error, e:
if e[0] == errno.EADDRINUSE: if e[0] == errno.EADDRINUSE:
self.logger.error("adding listener failed address: %s" % addr) self.logger.error("adding listener failed address: %s" % str(addr))
if i < tries: if i < tries:
self.logger.error("retrying in %s seconds." % str(delay)) self.logger.error("retrying in %s seconds." % str(delay))
time.sleep(delay) time.sleep(delay)
@ -90,16 +90,44 @@ class HTTPServer(object):
def join(self): def join(self):
# this pipe will be used to wake up the master when signal occurs # this pipe will be used to wake up the master when signal occurs
self.init_pipe() self.init_pipe()
respawn = True
while True:
try:
#if respawn:
#self.maintain_worker_count()
os.waitpid(-1, os.WNOHANG)
self.master_sleep()
except Exception, e:
self.logger.error("Unhandled exception [%s]" % str(e))
except KeyboardInterrupt:
self.kill_workers(signal.SIGQUIT)
sys.exit()
def master_sleep(self):
while True:
ready = select.select([self.PIPE[0]], [], [], 1)
if ready and ready[0]: break
try: try:
os.waitpid(-1, 0) while True:
data = os.read(self.PIPE[0], 4096)
except KeyboardInterrupt: if len(data) < 4096: return
self.kill_workers(signal.SIGQUIT) except errno.EAGAIN, errno.EINTR:
sys.exit() pass
def init_worker_process(self, worker): def init_worker_process(self, worker):
pass for w in self.WORKERS:
if w != worker:
try:
w.tmp.close()
except:
continue
else:
continue
[fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC) for sock in self.LISTENERS]
fcntl.fcntl(worker.tmp.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
def process_client(self, listener, conn, addr): def process_client(self, listener, conn, addr):
@ -114,17 +142,17 @@ class HTTPServer(object):
pid = os.fork() pid = os.fork()
if pid == 0: if pid == 0:
worker_pid = os.getpid() worker_pid = os.getpid()
yield worker_pid yield worker_pid
self.init_worker_process(worker) self.init_worker_process(worker)
alive = worker.tmp.fileno() alive = worker.tmp.fileno()
m = 0 m = 0
ready = self.LISTENERS ready = self.LISTENERS
try:
while alive: while alive:
m = 0 if m == 1 else 1 m = 0 if m == 1 else 1
os.fchmod(alive, m) os.fchmod(alive, m)
try:
for sock in ready: for sock in ready:
try: try:
self.process_client(sock, *sock.accept_nonblock()) self.process_client(sock, *sock.accept_nonblock())
@ -136,23 +164,23 @@ class HTTPServer(object):
m = 0 if m == 1 else 1 m = 0 if m == 1 else 1
os.fchmod(alive, m) os.fchmod(alive, m)
while True: while True:
try: try:
fd_sets = select.select([self.LISTENERS], [], self.PIPE, self.timeout) fd_sets = select.select(self.LISTENERS, [], self.PIPE, self.timeout)
if fd_sets: if fd_sets and fd_sets[0]:
ready = [fd_sets[0]] ready = [fd_sets[0]]
break break
except errno.EINTR: except errno.EINTR:
ready = self.LISTENERS ready = self.LISTENERS
except Exception, e: except Exception, e:
print str(e) self.logger.error("Unhandled exception in worker %s [%s]" % (worker_pid, e))
pass pass
except KeyboardInterrupt: except KeyboardInterrupt:
sys.exit() sys.exit()
except Exception, e: except Exception, e:
self.logger.error("Unhandled exception in worker %s [%s]" % (worker_pid, e)) self.logger.error("Unhandled exception in worker %s [%s]" % (worker_pid, e))
def kill_workers(self, sig): def kill_workers(self, sig):
"""kill all workers with signal sig """ """kill all workers with signal sig """
@ -165,7 +193,7 @@ class HTTPServer(object):
try: try:
os.kill(pid, sig) os.kill(pid, sig)
finally: finally:
worker.fd.close() worker.tmp.close()
del self.WORKERS[pid] del self.WORKERS[pid]
@ -184,8 +212,7 @@ class HTTPServer(object):
for pid, w in self.WORKERS.items(): for pid, w in self.WORKERS.items():
if w.nr >= self.worker_processes: if w.nr >= self.worker_processes:
self.kill_worker(pid, signal.SIGQUIT) self.kill_worker(pid, signal.SIGQUIT)
def init_pipe(self): def init_pipe(self):
if self.PIPE: if self.PIPE:

View File

@ -22,7 +22,7 @@ class TCPServer(socket.socket):
def __init__(self, address, **opts): def __init__(self, address, **opts):
self.address = address self.address = address
self.backlog = opts.get('timeout', 1024) self.backlog = opts.get('backlog', 1024)
self.timeout = opts.get('timeout', 300) self.timeout = opts.get('timeout', 300)
self.reuseaddr = opts.get('reuseaddr', True) self.reuseaddr = opts.get('reuseaddr', True)
self.nodelay = opts.get('nodelay', True) self.nodelay = opts.get('nodelay', True)

View File

@ -1,4 +1,4 @@
from gunicorn.httpserver import HTTPServer from gunicorn.httpserver import HTTPServer
if __name__ == '__main__': if __name__ == '__main__':
server = HTTPServer(None, 4).join() server = HTTPServer(None, 2).join()