diff --git a/game/evennia.py b/game/evennia.py index 9c358c69b0..a90ddfecd4 100755 --- a/game/evennia.py +++ b/game/evennia.py @@ -133,13 +133,10 @@ def start_daemon(parser, options, args): cycle_logfile() # Start it up - # Popen([TWISTED_BINARY, - # '--logfile=%s' % settings.DEFAULT_LOG_FILE, - # '--python=%s' % SERVER_PY_FILE]) - call([TWISTED_BINARY, - '--logfile=%s' % settings.DEFAULT_LOG_FILE, - '--python=%s' % SERVER_PY_FILE]) - + Popen([TWISTED_BINARY, + '--logfile=%s' % settings.DEFAULT_LOG_FILE, + '--python=%s' % SERVER_PY_FILE]) + def start_interactive(parser, options, args): """ diff --git a/src/server/server.py b/src/server/server.py index 6dfe71b8c6..2e20ee738f 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -18,6 +18,7 @@ if os.name == 'nt': from twisted.application import internet, service from twisted.internet import protocol, reactor, defer from twisted.web import server, static +from twisted.python import threadpool from django.db import connection from django.conf import settings from src.utils import reloads @@ -202,13 +203,14 @@ if WEBSERVER_ENABLED: # a django-compatible webserver. - from src.server.webserver import DjangoWebRoot + from src.server.webserver import DjangoWebRoot, WSGIWebServer#DjangoWebRoot - # define the root url (/) as a wsgi resource recognized by Django - web_root = DjangoWebRoot() + # start a thread pool and define the root url (/) as a wsgi resource + # recognized by Django + threads = threadpool.ThreadPool() + web_root = DjangoWebRoot(threads) # point our media resources to url /media - media_dir = os.path.join(settings.SRC_DIR, 'web', settings.MEDIA_URL.lstrip('/')) #TODO: Could be made cleaner? - web_root.putChild("media", static.File(media_dir)) + web_root.putChild("media", static.File(settings.MEDIA_ROOT)) if WEBCLIENT_ENABLED: # create ajax client processes at /webclientdata @@ -218,7 +220,8 @@ if WEBSERVER_ENABLED: web_site = server.Site(web_root, logPath=settings.HTTP_LOG_FILE) for port in WEBSERVER_PORTS: # create the webserver - webserver = internet.TCPServer(port, web_site) + webserver = WSGIWebServer(threads, port, web_site) + #webserver = internet.TCPServer(port, web_site) #webserver = internet.SSLServer(port, web_site) webserver.setName('EvenniaWebServer%s' % port) EVENNIA.services.addService(webserver) diff --git a/src/server/webserver.py b/src/server/webserver.py index 311cced08a..57cfea06de 100644 --- a/src/server/webserver.py +++ b/src/server/webserver.py @@ -14,6 +14,7 @@ a great example/aid on how to do this.) from twisted.web import resource from twisted.python import threadpool from twisted.internet import reactor +from twisted.application import service, internet from twisted.web.wsgi import WSGIResource from django.core.handlers.wsgi import WSGIHandler @@ -28,27 +29,12 @@ class DjangoWebRoot(resource.Resource): understands by tweaking the way the child instancee are recognized. """ - - def __init__(self): + def __init__(self, pool): """ Setup the django+twisted resource """ - resource.Resource.__init__(self) - self.wsgi_resource = self._wsgi_resource() - - def _wsgi_resource(self): - """ - Sets up a threaded webserver resource by tying - django and twisted together. - """ - # Start the threading - pool = threadpool.ThreadPool() - pool.start() - # Set it up so the pool stops after e.g. Ctrl-C kills the server - reactor.addSystemEventTrigger('after', 'shutdown', pool.stop) - # combine twisted's wsgi resource with django's wsgi handler - wsgi_resource = WSGIResource(reactor, pool, WSGIHandler()) - return wsgi_resource + resource.Resource.__init__(self) + self.wsgi_resource = WSGIResource(reactor, pool , WSGIHandler()) def getChild(self, path, request): """ @@ -58,3 +44,24 @@ class DjangoWebRoot(resource.Resource): path0 = request.prepath.pop(0) request.postpath.insert(0, path0) return self.wsgi_resource + +class WSGIWebServer(internet.TCPServer): + """ + This is a WSGI webserver. It makes sure to start + the threadpool after the service itself started, + so as to register correctly with the twisted daemon. + + call with WSGIWebServer(threadpool, port, wsgi_resource) + """ + def __init__(self, pool, *args, **kwargs ): + "This just stores the threadpool" + self.pool = pool + internet.TCPServer.__init__(self, *args, **kwargs) + def startService(self): + "Start the pool after the service" + internet.TCPServer.startService(self) + self.pool.start() + def stopService(self): + "Safely stop the pool after service stop." + internet.TCPServer.stopService(self) + self.pool.stop()