Ticket #5685: ticket_5685__revision_6453.patch

File ticket_5685__revision_6453.patch, 7.8 KB (added by __hawkeye__, 7 years ago)

First-pass implementation of this functionality. Lacks documentation.

  • django/conf/global_settings.py

     
    129129EMAIL_HOST_PASSWORD = ''
    130130EMAIL_USE_TLS = False
    131131
     132# List of functions to be called to setup the runtime environment
     133RUNTIME_SETUP_FUNCTIONS = ()
     134
    132135# List of strings representing installed apps.
    133136INSTALLED_APPS = ()
    134137
  • django/core/handlers/wsgi.py

     
    178178    raw_post_data = property(_get_raw_post_data)
    179179
    180180class WSGIHandler(BaseHandler):
    181     initLock = Lock()
    182 
    183181    def __call__(self, environ, start_response):
    184182        from django.conf import settings
    185183
    186         # Set up middleware if needed. We couldn't do this earlier, because
    187         # settings weren't available.
    188         if self._request_middleware is None:
    189             self.initLock.acquire()
    190             # Check that middleware is still uninitialised.
    191             if self._request_middleware is None:
    192                 self.load_middleware()
    193             self.initLock.release()
     184        # Perform state setup to ensure middleware is registered, among
     185        # other things.
     186        self.state.ensure_state()
    194187
    195188        dispatcher.send(signal=signals.request_started)
    196189        try:
  • django/core/handlers/base.py

     
    11from django.core import signals
    22from django.dispatch import dispatcher
     3from django.utils.setup import setup_runtime
    34from django import http
    45import sys
     6import threading
     7import logging
    58
    6 class BaseHandler(object):
     9class HandlerState(object):
     10    """
     11    A cache that stores/ensures state required for handling requests.
     12    """
     13    # Use the Borg pattern to share state between all instances. Details at
     14    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531.
     15    __shared_state = dict(
     16        request_middleware = [],
     17        view_middleware = [],
     18        response_middleware = [],
     19        exception_middleware = [],
     20        runtime_setup = False,  # Flag to monitor whether generic runtime environment setup has occured
     21
     22        # -- Variables used to setup the state --
     23        loaded = False,         # Flag to monitor the state of the cache
     24        write_lock = threading.RLock(),
     25    )
     26   
    727    def __init__(self):
    8         self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None
     28        self.__dict__ = self.__shared_state
     29   
     30    def ensure_state(self):
     31        """
     32        Fill in all the cache information, and perform any setup that is
     33        necessary. This method is threadsafe, in the sense that every caller
     34        will see the same state upon return, and if the cache is already
     35        initialised, it does no work.
     36        """
     37        if self.loaded:
     38            return
     39        self.write_lock.acquire()
     40        try:
     41            if self.loaded:
     42                return
    943
     44            setup_runtime()
     45            self.runtime_setup = True
     46
     47            self.load_middleware()
     48
     49            self.loaded = True
     50        finally:
     51            self.write_lock.release()
     52
    1053    def load_middleware(self):
    1154        """
    1255        Populate middleware lists from settings.MIDDLEWARE_CLASSES.
     
    1558        """
    1659        from django.conf import settings
    1760        from django.core import exceptions
    18         self._request_middleware = []
    19         self._view_middleware = []
    20         self._response_middleware = []
    21         self._exception_middleware = []
     61
    2262        for middleware_path in settings.MIDDLEWARE_CLASSES:
    2363            try:
    2464                dot = middleware_path.rindex('.')
     
    4080                continue
    4181
    4282            if hasattr(mw_instance, 'process_request'):
    43                 self._request_middleware.append(mw_instance.process_request)
     83                self.request_middleware.append(mw_instance.process_request)
    4484            if hasattr(mw_instance, 'process_view'):
    45                 self._view_middleware.append(mw_instance.process_view)
     85                self.view_middleware.append(mw_instance.process_view)
    4686            if hasattr(mw_instance, 'process_response'):
    47                 self._response_middleware.insert(0, mw_instance.process_response)
     87                self.response_middleware.insert(0, mw_instance.process_response)
    4888            if hasattr(mw_instance, 'process_exception'):
    49                 self._exception_middleware.insert(0, mw_instance.process_exception)
     89                self.exception_middleware.insert(0, mw_instance.process_exception)
    5090
     91handler_state = HandlerState()
     92
     93class BaseHandler(object):
     94    state = handler_state
     95    _request_middleware = handler_state.request_middleware
     96    _view_middleware = handler_state.view_middleware
     97    _response_middleware = handler_state.response_middleware
     98    _exception_middleware = handler_state.exception_middleware
     99
    51100    def get_response(self, request):
    52101        "Returns an HttpResponse object for the given HttpRequest"
    53102        response = self._real_get_response(request)
  • django/core/handlers/modpython.py

     
    144144        # that use settings now can work
    145145        from django.conf import settings
    146146
    147         # if we need to set up middleware, now that settings works we can do it now.
    148         if self._request_middleware is None:
    149             self.load_middleware()
     147        # Perform state setup to ensure middleware is registered, among
     148        # other things.
     149        self.state.ensure_state()
    150150
    151151        dispatcher.send(signal=signals.request_started)
    152152        try:
  • django/core/management/commands/shell.py

     
    11import os
    22from django.core.management.base import NoArgsCommand
     3from django.utils.setup import setup_runtime
    34from optparse import make_option
    45
    56class Command(NoArgsCommand):
     
    1213    requires_model_validation = False
    1314
    1415    def handle_noargs(self, **options):
     16        setup_runtime() # Perform some setup that may be necessary to get the runtime environment ready
     17
    1518        # XXX: (Temporary) workaround for ticket #1796: force early loading of all
    1619        # models from installed apps.
    1720        from django.db.models.loading import get_models
  • django/utils/setup.py

     
     1def setup_runtime():
     2    from django.conf import settings
     3   
     4    functions = []
     5
     6    for fn in settings.RUNTIME_SETUP_FUNCTIONS:
     7        i = fn.rfind('.')
     8        module, attr = fn[:i], fn[i+1:]
     9        try:
     10            mod = __import__(module, globals(), locals(), [attr])
     11        except ImportError, e:
     12            raise ImproperlyConfigured, 'Error importing module %s during runtime setup: "%s"' % (module, e)
     13        try:
     14            func = getattr(mod, attr)
     15            if not callable(func): raise AttributeError
     16        except AttributeError:
     17            raise ImproperlyConfigured, 'Module "%s" does not define a callable attribute "%s".' % (module, attr)
     18        else:
     19            try:
     20                ret_val = func()
     21            except Exception, e:
     22                raise ImproperlyConfigured, 'Exception occurred while running %s: "%s"' % (fn, e)
Back to Top