Adjusted the threaded webserver initialization to properly fit into the daemonization process when starting Evennia in threaded mode. Should behave the same way as interactive mode now. Resolves issue 125.

This commit is contained in:
Griatch 2011-02-23 21:08:02 +00:00
parent 606ce0c3c5
commit 7ebcefae2e
3 changed files with 38 additions and 31 deletions

View file

@ -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):
"""

View file

@ -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)

View file

@ -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()