Thursday, December 9, 2021

Database "InterfaceError connection already closed" with asgi.

 

Database "InterfaceError connection already closed" with asgi.

 

 

This often seems to happen when an exception was triggered, e.g., even

a simple Http404 due to incorrect URL.

 

A suspicion is discussed below. Ideas about this suspicion, how to

validate it and how to avoid the problem will be appreciated.

 

Note the following in django/core/handlers/exception.py:

 

    response = await sync_to_async(response_for_exception, thread_sensitive=False)(request, exc)

 

The "Asynchronous support" page:

 

  https://docs.djangoproject.com/en/3.1/topics/async/

 

    thread_sensitive=False: the sync function will run in a brand new

    thread which is then closed once the invocation completes.

 

We have an application (currently at Django 3.1.6) with a base

template that includes a banner with messages for users. It uses the

ORM to fetch the messages (if any) from the database. That base

template is also used for custom exception pages (e.g., handler404).

This appears to bite us in response_for_exception if it gets executed

in a different thread with a problematic database connection.

 

In several places Django uses sync_to_async with

thread_sensitive=True.  That is now also the default value (new True

in 3.1 vs old False in 3.0).

 

  https://docs.djangoproject.com/en/3.1/topics/async/ says:

 

    Warning

 

    asgiref version 3.3.0 changed the default value of the

    thread_sensitive parameter to True. This is a safer default, and

    in many cases interacting with Django the correct value, but be

    sure to evaluate uses of sync_to_async() if updating asgiref from

    a prior version.

 

So, shouldn't True be used in the above response_for_exception calls

as well, to allow safe use of the ORM in exception response

processing?

 

Similar reasoning may apply to django/contrib/staticfiles/handlers.py:

 

    return await sync_to_async(response_for_exception, thread_sensitive=False)(request, e)

 

Thanks.

 

 

No comments:

Post a Comment