Ben,

If lazy loading is causing you problems, here's good info on how to
force Django to load everything up front, by calling select_related()
and prefetch_related() in cases where you need to.  And also how to
make that the default via use_for_related_fields and custom managers:
- https://docs.djangoproject.com/en/1.9/topics/db/optimization/

--Fred
------------------------------------------------------------------------
Fred Stluka -- mailto:f...@bristle.com -- http://bristle.com/~fred/
Bristle Software, Inc -- http://bristle.com -- Glad to be of service!
Open Source: Without walls and fences, we need no Windows or Gates.
------------------------------------------------------------------------
On 3/27/16 4:15 PM, bliyan...@rentlytics.com wrote:
I'm not too familiar with the code you're referencing, but I'm personally really annoyed by lazy loading. It has a tendency to make selenium tests timeout inconsistently in CI, as well as give the impression to my bosses that the app is slow rather than just the first load which is usually what they see on new features.

-Ben

On Thursday, March 24, 2016 at 9:39:50 AM UTC-7, David Evans wrote:

    Hi all,

    Currently, middleware is initialized lazily on serving the first
    request, rather than on application start. There may well have
    been good reasons for this historically, but I don't think they
    apply any longer. Lazy initialization is unhelpful if a middleware
    class throws an error (e.g to report a misconfiguration) because
    the application will appear to start successfully and only later
    report the error when a request is made.

    I'd like to propose initializing middleware when
    `get_wsgi_application` is called. This solves the problem
    described above and, as far as I can tell, raises no backwards
    compatibility issues.

    More details on all this below.


    ### 1. Specific example of the problem

    I recently wrote an adapter for the WhiteNoise static file server
    so it could function as Django middleware as well as WSGI
    middleware (https://github.com/evansd/whitenoise
    <https://github.com/evansd/whitenoise>). WhiteNoise may be unusual
    in doing a non-trivial amount of work on initialization, but it
    doesn't seem unreasonable. When used as WSGI middleware any errors
    are triggered immediately on start up, but not so when used as
    Django middleware. This makes for a worse developer experience and
    an increased chance of deployment errors.


    ### 2. Reasons previously given for lazy initialization

    There was some brief discussion in this ticket 4 years ago:
    https://code.djangoproject.com/ticket/18577
    <https://code.djangoproject.com/ticket/18577>

    The reason given there is that "resolving on first request makes
    most sense, especially for the case where you might not be serving
    requests at all". Presumably this refers to running
    non-http-related management commands. But in those cases we never
    instantiate a WSGI application anyway (wsgi.py is just never
    imported) so this is no reason not to initialize eagerly when
    constructing the WSGI application. (Of course, things may have
    been different 4 years ago.)

    Another reason is given in the comments in django.core.handles.wsgi:
    
https://github.com/django/django/blob/3c1b572f1815c295878795b183b1957d0df2ca39/django/core/handlers/wsgi.py#L154
    
<https://github.com/django/django/blob/3c1b572f1815c295878795b183b1957d0df2ca39/django/core/handlers/wsgi.py#L154>

    This says "Set up middleware if needed. We couldn't do this
    earlier, because settings weren't available". However
    `get_wsgi_application` (the only public WSGI API) now calls
    `django.setup()` before constructing the handler so settings are
    in fact available.


    ### 3. Proposed solution

    My proposal is simply to amend `get_wsgi_application` as follows:

      def get_wsgi_application():
          django.setup(set_prefix=False)
          handler = WSGIHandler()
          handler.load_middleware()
          return handler

    It's possible that this logic could be moved into the handler's
    __init__ method. This caused no problems with existing application
    when I tried it, however it did cause problems with the test suite
    which seems to rely on the old behaviour in places. The above
    proposal passes all existing tests as is.


    ### 4. Backwards compatibility issues

    Middleware constructors have no means of accessing the request
    object or anything that depends on it. They are called right at
    the start of the handler's `__call__` method before the
    `request_started` signal is sent and before the `script_prefix`
    thread-local is set. Therefore it cannot matter, from the
    middleware class's perspective, whether it is instantiated before
    or after the first request comes in.


    I'm aware this issue probably isn't high on anyone else's priority
    list, but I think it would count as a genuine -- if small --
    improvement to Django.

    Thanks,

    Dave

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com <mailto:django-developers+unsubscr...@googlegroups.com>. To post to this group, send email to django-developers@googlegroups.com <mailto:django-developers@googlegroups.com>.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/f61a2b50-01e3-48ef-809f-82edc23d9da4%40googlegroups.com <https://groups.google.com/d/msgid/django-developers/f61a2b50-01e3-48ef-809f-82edc23d9da4%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django 
developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/56F861CF.8060909%40bristle.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to