summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlton Gibson <carlton.gibson@noumenal.es>2020-10-22 09:35:06 +0200
committerCarlton Gibson <carlton@noumenal.es>2020-10-27 11:24:07 +0100
commite17ee4468875077b90b70bb6a589ebad7493f757 (patch)
tree8223fa73e2205607e30cb30034667c2fc1bf1d6e
parent0b4fe82c7405ba96f2eb25b954a8f498cc8364b3 (diff)
Fixed #32128 -- Added asgiref 3.3 compatibility.
Thread sensitive parameter is True by default from asgiref v3.3.0. Added an explicit thread_sensitive=False to previously implicit uses.
-rw-r--r--django/contrib/staticfiles/handlers.py4
-rw-r--r--django/core/handlers/base.py2
-rw-r--r--django/core/handlers/exception.py2
-rw-r--r--django/test/client.py6
-rw-r--r--docs/releases/3.1.3.txt2
-rw-r--r--docs/topics/async.txt24
6 files changed, 25 insertions, 15 deletions
diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py
index 2ee826e2de..44fef0722d 100644
--- a/django/contrib/staticfiles/handlers.py
+++ b/django/contrib/staticfiles/handlers.py
@@ -56,9 +56,9 @@ class StaticFilesHandlerMixin:
async def get_response_async(self, request):
try:
- return await sync_to_async(self.serve)(request)
+ return await sync_to_async(self.serve, thread_sensitive=False)(request)
except Http404 as e:
- return await sync_to_async(response_for_exception)(request, e)
+ return await sync_to_async(response_for_exception, thread_sensitive=False)(request, e)
class StaticFilesHandler(StaticFilesHandlerMixin, WSGIHandler):
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index 169df6b3cf..8e8c3da06a 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -148,7 +148,7 @@ class BaseHandler:
response = await self._middleware_chain(request)
response._resource_closers.append(request.close)
if response.status_code >= 400:
- await sync_to_async(log_response)(
+ await sync_to_async(log_response, thread_sensitive=False)(
'%s: %s', response.reason_phrase, request.path,
response=response,
request=request,
diff --git a/django/core/handlers/exception.py b/django/core/handlers/exception.py
index 70b23edb62..3005a5eccb 100644
--- a/django/core/handlers/exception.py
+++ b/django/core/handlers/exception.py
@@ -37,7 +37,7 @@ def convert_exception_to_response(get_response):
try:
response = await get_response(request)
except Exception as exc:
- response = await sync_to_async(response_for_exception)(request, exc)
+ response = await sync_to_async(response_for_exception, thread_sensitive=False)(request, exc)
return response
return inner
else:
diff --git a/django/test/client.py b/django/test/client.py
index 1e6d9e2a39..ba1c37ed59 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -181,7 +181,7 @@ class AsyncClientHandler(BaseHandler):
body_file = FakePayload('')
request_started.disconnect(close_old_connections)
- await sync_to_async(request_started.send)(sender=self.__class__, scope=scope)
+ await sync_to_async(request_started.send, thread_sensitive=False)(sender=self.__class__, scope=scope)
request_started.connect(close_old_connections)
request = ASGIRequest(scope, body_file)
# Sneaky little hack so that we can easily get round
@@ -197,14 +197,14 @@ class AsyncClientHandler(BaseHandler):
response.asgi_request = request
# Emulate a server by calling the close method on completion.
if response.streaming:
- response.streaming_content = await sync_to_async(closing_iterator_wrapper)(
+ response.streaming_content = await sync_to_async(closing_iterator_wrapper, thread_sensitive=False)(
response.streaming_content,
response.close,
)
else:
request_finished.disconnect(close_old_connections)
# Will fire request_finished.
- await sync_to_async(response.close)()
+ await sync_to_async(response.close, thread_sensitive=False)()
request_finished.connect(close_old_connections)
return response
diff --git a/docs/releases/3.1.3.txt b/docs/releases/3.1.3.txt
index 6f526aa5c9..300e4aff54 100644
--- a/docs/releases/3.1.3.txt
+++ b/docs/releases/3.1.3.txt
@@ -51,3 +51,5 @@ Bugfixes
* Fixed a regression in Django 3.1 that invalidated pre-Django 3.1 password
reset tokens (:ticket:`32130`).
+
+* Added support for ``asgiref`` 3.3 (:ticket:`32128`).
diff --git a/docs/topics/async.txt b/docs/topics/async.txt
index a2f702b8e3..b25dee7605 100644
--- a/docs/topics/async.txt
+++ b/docs/topics/async.txt
@@ -214,14 +214,14 @@ as ensuring threadlocals work, it also enables the ``thread_sensitive`` mode of
``sync_to_async()``
-------------------
-.. function:: sync_to_async(sync_function, thread_sensitive=False)
+.. function:: sync_to_async(sync_function, thread_sensitive=True)
Takes a sync function and returns an async function that wraps it. Can be used
as either a direct wrapper or a decorator::
from asgiref.sync import sync_to_async
- async_function = sync_to_async(sync_function)
+ async_function = sync_to_async(sync_function, thread_sensitive=False)
async_function = sync_to_async(sensitive_sync_function, thread_sensitive=True)
@sync_to_async
@@ -234,13 +234,21 @@ directions.
Sync functions tend to be written assuming they all run in the main
thread, so :func:`sync_to_async` has two threading modes:
-* ``thread_sensitive=False`` (the default): the sync function will run in a
- brand new thread which is then closed once the invocation completes.
+* ``thread_sensitive=True`` (the default): the sync function will run in the
+ same thread as all other ``thread_sensitive`` functions. This will be the
+ main thread, if the main thread is synchronous and you are using the
+ :func:`async_to_sync` wrapper.
-* ``thread_sensitive=True``: the sync function will run in the same thread as
- all other ``thread_sensitive`` functions. This will be the main thread, if
- the main thread is synchronous and you are using the :func:`async_to_sync`
- wrapper.
+* ``thread_sensitive=False``: the sync function will run in a brand new thread
+ which is then closed once the invocation completes.
+
+.. 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.
Thread-sensitive mode is quite special, and does a lot of work to run all
functions in the same thread. Note, though, that it *relies on usage of*