2012-10-10 00:16:25 +02:00
|
|
|
#!/usr/bin/env python
|
2012-11-08 23:23:25 +01:00
|
|
|
import optparse
|
2012-10-10 00:16:25 +02:00
|
|
|
import subprocess
|
2012-11-09 20:59:43 +01:00
|
|
|
import signal
|
2012-11-14 19:46:12 +01:00
|
|
|
import traceback
|
2013-10-23 19:12:03 +02:00
|
|
|
import sys
|
2012-10-10 00:16:25 +02:00
|
|
|
import os
|
|
|
|
|
|
|
|
from twisted.internet import reactor
|
|
|
|
from twisted.web import proxy, server, resource
|
|
|
|
|
2013-08-21 18:01:40 +02:00
|
|
|
# Monkey-patch twisted.web.http to avoid request.finish exceptions
|
2013-09-05 21:24:18 +02:00
|
|
|
# https://trac.zulip.net/ticket/1728
|
2013-08-21 18:01:40 +02:00
|
|
|
from twisted.web.http import Request
|
|
|
|
orig_finish = Request.finish
|
|
|
|
def patched_finish(self):
|
|
|
|
if self._disconnected:
|
|
|
|
return
|
|
|
|
return orig_finish(self)
|
|
|
|
Request.finish = patched_finish
|
|
|
|
|
2012-11-08 23:23:25 +01:00
|
|
|
parser = optparse.OptionParser(r"""
|
|
|
|
|
2012-10-10 00:16:25 +02:00
|
|
|
Starts the app listening on localhost, for local development.
|
|
|
|
|
|
|
|
This script launches the Django and Tornado servers, then runs a reverse proxy
|
|
|
|
which serves to both of them. After it's all up and running, browse to
|
|
|
|
|
|
|
|
http://localhost:9991/
|
|
|
|
|
|
|
|
Note that, while runserver and runtornado have the usual auto-restarting
|
|
|
|
behavior, the reverse proxy itself does *not* automatically restart on changes
|
|
|
|
to this file.
|
2012-11-08 23:23:25 +01:00
|
|
|
""")
|
|
|
|
|
|
|
|
parser.add_option('--test',
|
|
|
|
action='store_true', dest='test',
|
|
|
|
help='Use the testing database and ports')
|
|
|
|
|
2013-12-16 20:19:02 +01:00
|
|
|
parser.add_option('--minimal',
|
|
|
|
action='store_true', dest='minimal',
|
|
|
|
help='Start only "essential" workers')
|
2013-12-13 16:17:27 +01:00
|
|
|
|
2012-11-08 23:23:25 +01:00
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
|
|
|
|
base_port = 9991
|
|
|
|
manage_args = ''
|
|
|
|
if options.test:
|
|
|
|
base_port = 9981
|
2013-10-23 19:12:03 +02:00
|
|
|
settings_module = "zproject.test_settings"
|
|
|
|
else:
|
|
|
|
settings_module = "zproject.settings"
|
|
|
|
|
|
|
|
manage_args = '--settings=%s' % (settings_module,)
|
|
|
|
os.environ['DJANGO_SETTINGS_MODULE'] = settings_module
|
|
|
|
|
|
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
2012-10-10 00:16:25 +02:00
|
|
|
|
2012-11-08 23:23:25 +01:00
|
|
|
proxy_port = base_port
|
|
|
|
django_port = base_port+1
|
|
|
|
tornado_port = base_port+2
|
2012-10-10 00:16:25 +02:00
|
|
|
proxy_host = 'localhost:%d' % (proxy_port,)
|
|
|
|
|
2013-10-28 15:54:32 +01:00
|
|
|
os.chdir(os.path.join(os.path.dirname(__file__), '..'))
|
2012-10-10 00:16:25 +02:00
|
|
|
|
2013-03-25 23:21:39 +01:00
|
|
|
# Clean up stale .pyc files etc.
|
|
|
|
subprocess.check_call('./tools/clean-repo')
|
|
|
|
|
2014-01-09 23:33:31 +01:00
|
|
|
# Watch for handlebars changes.
|
|
|
|
subprocess.Popen('./tools/compile-handlebars-templates forever', shell=True)
|
|
|
|
|
2012-11-09 20:59:43 +01:00
|
|
|
# Set up a new process group, so that we can later kill run{server,tornado}
|
|
|
|
# and all of the processes they spawn.
|
|
|
|
os.setpgrp()
|
|
|
|
|
2013-01-30 23:35:24 +01:00
|
|
|
# Pass --nostatic because we configure static serving ourselves in
|
2013-10-04 19:27:01 +02:00
|
|
|
# zulip/urls.py.
|
2013-10-23 19:12:03 +02:00
|
|
|
cmds = ['python manage.py runserver --nostatic %s localhost:%d'
|
|
|
|
% (manage_args, django_port),
|
|
|
|
'python manage.py runtornado %s localhost:%d'
|
|
|
|
% (manage_args, tornado_port)]
|
2013-12-13 16:17:27 +01:00
|
|
|
|
2013-12-16 20:19:02 +01:00
|
|
|
if options.minimal:
|
|
|
|
queues = ['message_sender', 'user_presence']
|
|
|
|
else:
|
2013-12-13 16:17:27 +01:00
|
|
|
from zerver.worker.queue_processors import get_active_worker_queues
|
2013-12-16 20:19:02 +01:00
|
|
|
queues = get_active_worker_queues()
|
|
|
|
|
|
|
|
for queue in queues:
|
|
|
|
cmds.append('python manage.py process_queue %s %s' %(manage_args, queue))
|
2013-10-23 19:12:03 +02:00
|
|
|
|
|
|
|
for cmd in cmds:
|
2012-11-09 20:59:43 +01:00
|
|
|
subprocess.Popen(cmd, shell=True)
|
2012-10-10 00:16:25 +02:00
|
|
|
|
|
|
|
class Resource(resource.Resource):
|
|
|
|
def getChild(self, name, request):
|
|
|
|
request.requestHeaders.setRawHeaders('X-Forwarded-Host', [proxy_host])
|
|
|
|
|
2013-11-05 17:02:34 +01:00
|
|
|
if (request.uri in ['/json/get_events'] or
|
2013-11-19 23:11:30 +01:00
|
|
|
request.uri.startswith('/json/events') or
|
2013-09-07 00:27:10 +02:00
|
|
|
request.uri.startswith('/api/v1/events') or
|
|
|
|
request.uri.startswith('/sockjs')):
|
2012-11-08 23:23:25 +01:00
|
|
|
return proxy.ReverseProxyResource('localhost', tornado_port, '/'+name)
|
2012-10-10 00:16:25 +02:00
|
|
|
|
2012-11-08 23:23:25 +01:00
|
|
|
return proxy.ReverseProxyResource('localhost', django_port, '/'+name)
|
2012-10-10 00:16:25 +02:00
|
|
|
|
|
|
|
try:
|
2012-11-14 19:43:27 +01:00
|
|
|
reactor.listenTCP(proxy_port, server.Site(Resource()), interface='127.0.0.1')
|
2012-10-10 00:16:25 +02:00
|
|
|
reactor.run()
|
2012-11-14 19:46:12 +01:00
|
|
|
except:
|
|
|
|
# Print the traceback before we get SIGTERM and die.
|
|
|
|
traceback.print_exc()
|
|
|
|
raise
|
2012-10-10 00:16:25 +02:00
|
|
|
finally:
|
2012-11-09 20:59:43 +01:00
|
|
|
# Kill everything in our process group.
|
|
|
|
os.killpg(0, signal.SIGTERM)
|