diff --git a/evennia/server/server.py b/evennia/server/server.py index b5a1aff514..c8c75835e7 100644 --- a/evennia/server/server.py +++ b/evennia/server/server.py @@ -151,7 +151,8 @@ class Evennia(object): sys.path.insert(1, '.') # create a store of services - self.services = service.IServiceCollection(application) + self.services = service.MultiService() + self.services.setServiceParent(application) self.amp_protocol = None # set by amp factory self.sessions = SESSIONS self.sessions.server = self @@ -348,6 +349,10 @@ class Evennia(object): from evennia.server.models import ServerConfig from evennia.utils import gametime as _GAMETIME_MODULE + if WEBSERVER_ENABLED: + # finish all pending web requests. Otherwise stopping threadpool will cause deadlock. + yield self.web_root.get_pending_requests() + if mode == 'reload': # call restart hooks ServerConfig.objects.conf("server_restart_mode", "reload") @@ -533,11 +538,13 @@ if WEBSERVER_ENABLED: # recognized by Django threads = threadpool.ThreadPool(minthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[0]), maxthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[1])) + web_root = DjangoWebRoot(threads) # point our media resources to url /media web_root.putChild("media", static.File(settings.MEDIA_ROOT)) # point our static resources to url /static web_root.putChild("static", static.File(settings.STATIC_ROOT)) + EVENNIA.web_root = web_root if WEB_PLUGINS_MODULE: # custom overloads diff --git a/evennia/server/webserver.py b/evennia/server/webserver.py index e974226f7f..7144c481aa 100644 --- a/evennia/server/webserver.py +++ b/evennia/server/webserver.py @@ -28,6 +28,7 @@ from evennia.utils import logger _UPSTREAM_IPS = settings.UPSTREAM_IPS _DEBUG = settings.DEBUG + # # X-Forwarded-For Handler # @@ -117,6 +118,8 @@ class DjangoWebRoot(resource.Resource): understands by tweaking the way child instancee ars recognized. """ + open_requests = [] + def __init__(self, pool): """ Setup the django+twisted resource. @@ -128,6 +131,21 @@ class DjangoWebRoot(resource.Resource): resource.Resource.__init__(self) self.wsgi_resource = WSGIResource(reactor, pool, WSGIHandler()) + def get_pending_requests(self): + """ + Converts our open_requests list of deferreds into a DeferredList + + Returns: + d_list (deferred): A DeferredList object of all our requests + """ + from twisted.internet import defer + return defer.DeferredList(self.open_requests, consumeErrors=True) + + def _decrement_requests(self, *args, **kwargs): + deferred = kwargs.get('deferred', None) + if deferred in self.open_requests: + self.open_requests.remove(deferred) + def getChild(self, path, request): """ To make things work we nudge the url tree to make this the @@ -140,8 +158,12 @@ class DjangoWebRoot(resource.Resource): """ path0 = request.prepath.pop(0) request.postpath.insert(0, path0) + deferred = request.notifyFinish() + self.open_requests.append(deferred) + deferred.addBoth(self._decrement_requests, deferred=deferred) return self.wsgi_resource + # # Site with deactivateable logging # @@ -151,11 +173,13 @@ class Website(server.Site): This class will only log http requests if settings.DEBUG is True. """ noisy = False + def log(self, request): - "Conditional logging" + """Conditional logging""" if _DEBUG: server.Site.log(self, request) + # # Threaded Webserver #