[3.0.x] Fixed #31253 -- Fixed data loss possibility when using caching from async code.

Case missed in a415ce70be.

Backport of e3f6e18513 from master
This commit is contained in:
Jon Dufresne 2020-02-06 17:59:20 -08:00 committed by Mariusz Felisiak
parent dc0dfd1dac
commit 7540b7eb31
3 changed files with 17 additions and 3 deletions

View File

@ -12,7 +12,7 @@ object.
See docs/topics/cache.txt for information on the public API.
"""
from threading import local
from asgiref.local import Local
from django.conf import settings
from django.core import signals
@ -61,7 +61,7 @@ class CacheHandler:
Ensure only one instance of each alias exists per thread.
"""
def __init__(self):
self._caches = local()
self._caches = Local()
def __getitem__(self, alias):
try:

View File

@ -9,4 +9,5 @@ Django 3.0.4 fixes several bugs in 3.0.3.
Bugfixes
========
* ...
* Fixed a data loss possibility when using caching from async code
(:ticket:`31253`).

View File

@ -4,6 +4,7 @@ from unittest import mock, skipIf
from asgiref.sync import async_to_sync
from django.core.cache import DEFAULT_CACHE_ALIAS, caches
from django.core.exceptions import SynchronousOnlyOperation
from django.test import SimpleTestCase
from django.utils.asyncio import async_unsafe
@ -11,6 +12,18 @@ from django.utils.asyncio import async_unsafe
from .models import SimpleModel
@skipIf(sys.platform == 'win32' and (3, 8, 0) < sys.version_info < (3, 8, 1), 'https://bugs.python.org/issue38563')
class CacheTest(SimpleTestCase):
def test_caches_local(self):
@async_to_sync
async def async_cache():
return caches[DEFAULT_CACHE_ALIAS]
cache_1 = async_cache()
cache_2 = async_cache()
self.assertIs(cache_1, cache_2)
@skipIf(sys.platform == 'win32' and (3, 8, 0) < sys.version_info < (3, 8, 1), 'https://bugs.python.org/issue38563')
class DatabaseConnectionTest(SimpleTestCase):
"""A database connection cannot be used in an async context."""