Browse Source

Fixed #26452 -- Loaded middleware on server start rather than on first request.

David Evans 9 years ago
parent
commit
99bb7fcc18
4 changed files with 15 additions and 24 deletions
  1. 4 10
      django/core/handlers/wsgi.py
  2. 3 0
      docs/releases/1.10.txt
  3. 6 2
      docs/topics/http/middleware.txt
  4. 2 12
      tests/handlers/tests.py

+ 4 - 10
django/core/handlers/wsgi.py

@@ -6,7 +6,6 @@ import logging
 import re
 import sys
 from io import BytesIO
-from threading import Lock
 
 from django import http
 from django.conf import settings
@@ -147,18 +146,13 @@ class WSGIRequest(http.HttpRequest):
 
 
 class WSGIHandler(base.BaseHandler):
-    initLock = Lock()
     request_class = WSGIRequest
 
-    def __call__(self, environ, start_response):
-        # Set up middleware if needed. We couldn't do this earlier, because
-        # settings weren't available.
-        if self._request_middleware is None:
-            with self.initLock:
-                # Check that middleware is still uninitialized.
-                if self._request_middleware is None:
-                    self.load_middleware()
+    def __init__(self, *args, **kwargs):
+        super(WSGIHandler, self).__init__(*args, **kwargs)
+        self.load_middleware()
 
+    def __call__(self, environ, start_response):
         set_script_prefix(get_script_name(environ))
         signals.request_started.send(sender=self.__class__, environ=environ)
         try:

+ 3 - 0
docs/releases/1.10.txt

@@ -714,6 +714,9 @@ Miscellaneous
   :class:`~django.contrib.postgres.fields.RangeField`, you should change the
   ``base_field`` attribute.
 
+* Middleware classes are now initialized when the server starts rather than
+  during the first request.
+
 .. _deprecated-features-1.10:
 
 Features deprecated in 1.10

+ 6 - 2
docs/topics/http/middleware.txt

@@ -260,8 +260,12 @@ of caveats:
   define ``__init__`` as requiring any arguments.
 
 * Unlike the ``process_*`` methods which get called once per request,
-  ``__init__`` gets called only *once*, when the Web server responds to the
-  first request.
+  ``__init__`` gets called only *once*, when the Web server starts.
+
+.. versionchanged:: 1.10
+
+    In older versions, ``__init__`` was not called until the Web server
+    responded to its first request.
 
 Marking middleware as unused
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ 2 - 12
tests/handlers/tests.py

@@ -20,19 +20,9 @@ class HandlerTests(SimpleTestCase):
     def tearDown(self):
         request_started.connect(close_old_connections)
 
-    # Mangle settings so the handler will fail
-    @override_settings(MIDDLEWARE_CLASSES=42)
-    def test_lock_safety(self):
-        """
-        Tests for bug #11193 (errors inside middleware shouldn't leave
-        the initLock locked).
-        """
-        # Try running the handler, it will fail in load_middleware
+    def test_middleware_initialized(self):
         handler = WSGIHandler()
-        self.assertEqual(handler.initLock.locked(), False)
-        with self.assertRaises(Exception):
-            handler(None, None)
-        self.assertEqual(handler.initLock.locked(), False)
+        self.assertIsNotNone(handler._request_middleware)
 
     def test_bad_path_info(self):
         """Tests for bug #15672 ('request' referenced before assignment)"""