Created
January 10, 2010 04:09
-
-
Save ericflo/273327 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copypasta of Django's runserver management command, modified to use gunicorn http://github.com/benoitc/gunicorn | |
import os | |
import signal | |
import sys | |
import threading | |
import time | |
from optparse import make_option | |
import django | |
from django.core.management.base import BaseCommand, CommandError | |
from django.conf import settings | |
from django.utils import translation | |
from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException | |
from django.core.handlers.wsgi import WSGIHandler | |
from gunicorn.arbiter import Arbiter | |
RUN_RELOADER = True | |
_mtimes = {} | |
_win = (sys.platform == "win32") | |
def _getfile(m): | |
return getattr(m, "__file__", None) | |
def code_changed(): | |
global _mtimes | |
for fn in filter(bool, map(_getfile, sys.modules.values())): | |
if fn.endswith('.pyc') or fn.endswith('.pyo'): | |
fn = fn[:-1] | |
if not os.path.exists(fn): | |
continue # File might be in an egg, so it can't be reloaded. | |
stat = os.stat(fn) | |
mtime = stat.st_mtime | |
if _win: | |
mtime -= stat.st_ctime | |
if fn not in _mtimes: | |
_mtimes[fn] = mtime | |
continue | |
if mtime != _mtimes[fn]: | |
_mtimes = {} | |
return True | |
return False | |
def reloader_thread(): | |
print 'Starting up the reloader thread' | |
while RUN_RELOADER: | |
if code_changed(): | |
pid = os.getpid() | |
print 'Changes detected, sending HUP signal to Arbiter %s' % (pid,) | |
os.kill(pid, signal.SIGHUP) | |
time.sleep(1) | |
class Command(BaseCommand): | |
option_list = BaseCommand.option_list + ( | |
make_option('--noreload', action='store_false', dest='use_reloader', default=True, | |
help='Tells Django to NOT use the auto-reloader.'), | |
make_option('--adminmedia', dest='admin_media_path', default='', | |
help='Specifies the directory from which to serve admin media.'), | |
make_option('--workers', dest='workers', default='1', | |
help='Specifies the number of worker processes to use.') | |
) | |
help = "Starts a fully-functional Web server for development." | |
args = '[optional port number, or ipaddr:port]' | |
# Validation is called explicitly each time the server is reloaded. | |
requires_model_validation = False | |
def handle(self, addrport='', *args, **options): | |
global RUN_RELOADER | |
if args: | |
raise CommandError('Usage is runserver %s' % self.args) | |
if not addrport: | |
addr = '' | |
port = '8000' | |
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) | |
use_reloader = options.get('use_reloader', True) | |
admin_media_path = options.get('admin_media_path', '') | |
workers = int(options.get('workers', '1')) | |
quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C' | |
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) | |
print "Quit the server with %s." % quit_command | |
# django.core.management.base forces the locale to en-us. | |
translation.activate(settings.LANGUAGE_CODE) | |
if use_reloader: | |
reloader = threading.Thread(target=reloader_thread) | |
reloader.start() | |
try: | |
handler = AdminMediaHandler(WSGIHandler(), admin_media_path) | |
arbiter = Arbiter((addr, int(port)), workers, handler) | |
arbiter.run() | |
except WSGIServerException, e: | |
# Use helpful error messages instead of ugly tracebacks. | |
ERRORS = { | |
13: "You don't have permission to access that port.", | |
98: "That port is already in use.", | |
99: "That IP address can't be assigned-to.", | |
} | |
try: | |
error_text = ERRORS[e.args[0].args[0]] | |
except (AttributeError, KeyError): | |
error_text = str(e) | |
sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') | |
sys.exit(1) | |
# This process has terminated, so we should tell the reloader to stop | |
# going as well. | |
RUN_RELOADER = False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment