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