mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
branch to handle unix sockets
This commit is contained in:
parent
e804f97f5e
commit
0935ab3344
@ -140,7 +140,7 @@ class Arbiter(object):
|
||||
self.log.error("should be a non GUNICORN environnement")
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
for i in range(5):
|
||||
try:
|
||||
sock = self.init_socket(addr)
|
||||
@ -152,30 +152,46 @@ class Arbiter(object):
|
||||
if i < 5:
|
||||
self.log.error("Retrying in 1 second.")
|
||||
time.sleep(1)
|
||||
if self.LISTENER:
|
||||
self.log.info("Listen on %s:%s" % self.LISTENER.getsockname())
|
||||
|
||||
if self.LISTENER:
|
||||
try:
|
||||
self.log.info("Listen on %s:%s" % self.LISTENER.getsockname())
|
||||
except TypeError:
|
||||
self.log.info("Listen on %s" % self.LISTENER.getsockname())
|
||||
def init_socket_fromfd(self, fd, address):
|
||||
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.set_sockopts(sock)
|
||||
if isinstance(address, basestring):
|
||||
sock = socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
else:
|
||||
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.set_tcp_sockopts(sock)
|
||||
self.set_sockopts(sock, address)
|
||||
return sock
|
||||
|
||||
def init_socket(self, address):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.set_sockopts(sock)
|
||||
sock.bind(address)
|
||||
sock.listen(2048)
|
||||
if isinstance(address, basestring):
|
||||
try:
|
||||
os.remove(address)
|
||||
except OSError:
|
||||
pass
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
else:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.set_tcp_sockopts(sock)
|
||||
self.set_sockopts(sock, address)
|
||||
return sock
|
||||
|
||||
def set_sockopts(self, sock):
|
||||
sock.setblocking(0)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
def set_tcp_sockopts(self, sock):
|
||||
if hasattr(socket, "TCP_CORK"):
|
||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_CORK, 1)
|
||||
elif hasattr(socket, "TCP_NOPUSH"):
|
||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NOPUSH, 1)
|
||||
|
||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
|
||||
def set_sockopts(self, sock, address):
|
||||
sock.setblocking(0)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.bind(address)
|
||||
sock.listen(2048)
|
||||
|
||||
def run(self):
|
||||
self.start()
|
||||
self.manage_workers()
|
||||
|
||||
@ -28,10 +28,8 @@ UMASK = 0
|
||||
|
||||
def options():
|
||||
return [
|
||||
op.make_option('--host', dest='host',
|
||||
help='Host to listen on. [%default]'),
|
||||
op.make_option('--port', dest='port', type='int',
|
||||
help='Port to listen on. [%default]'),
|
||||
op.make_option('-b', '--bind', dest='bind',
|
||||
help='Adress to listen on. Ex. host:port or unix://path/to/socketfile'),
|
||||
op.make_option('--workers', dest='workers', type='int',
|
||||
help='Number of workers to spawn. [%default]'),
|
||||
op.make_option('-p','--pid', dest='pidfile',
|
||||
@ -95,21 +93,26 @@ def main(usage, get_app):
|
||||
if opts.debug:
|
||||
workers = 1
|
||||
|
||||
host = opts.host or '127.0.0.1'
|
||||
port = opts.port
|
||||
if port is None:
|
||||
if ':' in host:
|
||||
host, port = host.split(':', 1)
|
||||
bind = opts.bind or '127.0.0.1'
|
||||
if bind.startswith("unix:"):
|
||||
addr = bind.split("unix:")[1]
|
||||
else:
|
||||
if ':' in bind:
|
||||
host, port = bind.split(':', 1)
|
||||
if not port.isdigit():
|
||||
raise RuntimeError("%r is not a valid port number." % port)
|
||||
port = int(port)
|
||||
else:
|
||||
host = bind
|
||||
port = 8000
|
||||
addr = (host, port)
|
||||
|
||||
kwargs = dict(
|
||||
debug=opts.debug,
|
||||
pidfile=opts.pidfile
|
||||
)
|
||||
|
||||
arbiter = Arbiter((host,port), workers, app,
|
||||
arbiter = Arbiter(addr, workers, app,
|
||||
**kwargs)
|
||||
if opts.daemon:
|
||||
daemonize()
|
||||
@ -229,8 +232,9 @@ def run_paster():
|
||||
else:
|
||||
workers = int(ctx.local_conf.get('workers', 1))
|
||||
|
||||
opts.host = opts.host or ctx.local_conf.get('host', '127.0.0.1')
|
||||
opts.port = opts.port or int(ctx.local_conf.get('port', 8000))
|
||||
host = opts.host or ctx.local_conf.get('host', '127.0.0.1')
|
||||
port = opts.port or int(ctx.local_conf.get('port', 8000))
|
||||
bind = "%s:%s" % (host, port)
|
||||
|
||||
debug = ctx.global_conf.get('debug') == "true"
|
||||
if debug:
|
||||
|
||||
@ -30,7 +30,7 @@ class Command(BaseCommand):
|
||||
help='Run daemonized in the background.'),
|
||||
)
|
||||
help = "Starts a fully-functional Web server using gunicorn."
|
||||
args = '[optional port number, or ipaddr:port]'
|
||||
args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]'
|
||||
|
||||
# Validation is called explicitly each time the server is reloaded.
|
||||
requires_model_validation = False
|
||||
@ -38,20 +38,21 @@ class Command(BaseCommand):
|
||||
def handle(self, addrport='', *args, **options):
|
||||
if args:
|
||||
raise CommandError('Usage is runserver %s' % self.args)
|
||||
if not addrport:
|
||||
addr = ''
|
||||
port = '8000'
|
||||
|
||||
bind = addrport or '127.0.0.1'
|
||||
if bind.startswith("unix:"):
|
||||
addr = bind.split("unix:")[1]
|
||||
else:
|
||||
try:
|
||||
addr, port = addrport.split(':')
|
||||
except ValueError:
|
||||
addr, port = '', addrport
|
||||
if not addr:
|
||||
addr = '127.0.0.1'
|
||||
|
||||
if not port.isdigit():
|
||||
raise CommandError("%r is not a valid port number." % port)
|
||||
|
||||
if ':' in bind:
|
||||
host, port = host.split(':', 1)
|
||||
if not port.isdigit():
|
||||
raise CommandError("%r is not a valid port number." % port)
|
||||
port = int(port)
|
||||
else:
|
||||
host = bind
|
||||
port = 8000
|
||||
addr = (host, port)
|
||||
|
||||
admin_media_path = options.get('admin_media_path', '')
|
||||
workers = int(options.get('workers', '1'))
|
||||
daemon = options.get('daemon')
|
||||
@ -61,7 +62,11 @@ class Command(BaseCommand):
|
||||
print "Validating models..."
|
||||
self.validate(display_num_errors=True)
|
||||
print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE)
|
||||
print "Development server is running at http://%s:%s/" % (addr, port)
|
||||
|
||||
if isinstance(address, basestring):
|
||||
print "Development server is running at unix:/" % addr
|
||||
else:
|
||||
print "Development server is running at http://%s:%s/" % addr
|
||||
print "Quit the server with %s." % quit_command
|
||||
|
||||
# django.core.management.base forces the locale to en-us.
|
||||
@ -69,7 +74,7 @@ class Command(BaseCommand):
|
||||
|
||||
try:
|
||||
handler = AdminMediaHandler(WSGIHandler(), admin_media_path)
|
||||
arbiter = Arbiter((addr, int(port)), workers, handler,
|
||||
arbiter = Arbiter(addr, workers, handler,
|
||||
pidfile=pidfile)
|
||||
if daemon:
|
||||
daemonize()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user