1
0
mirror of https://github.com/django/django.git synced 2025-01-03 15:06:09 +00:00

Fixed #31253 -- Fixed data loss possibility when using caching from async code.

Case missed in a415ce70be.
This commit is contained in:
Jon Dufresne 2020-02-06 17:59:20 -08:00 committed by Mariusz Felisiak
parent 20ba3ce4ac
commit e3f6e18513
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. 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.conf import settings
from django.core import signals from django.core import signals
@ -61,7 +61,7 @@ class CacheHandler:
Ensure only one instance of each alias exists per thread. Ensure only one instance of each alias exists per thread.
""" """
def __init__(self): def __init__(self):
self._caches = local() self._caches = Local()
def __getitem__(self, alias): def __getitem__(self, alias):
try: try:

View File

@ -9,4 +9,5 @@ Django 3.0.4 fixes several bugs in 3.0.3.
Bugfixes 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 asgiref.sync import async_to_sync
from django.core.cache import DEFAULT_CACHE_ALIAS, caches
from django.core.exceptions import SynchronousOnlyOperation from django.core.exceptions import SynchronousOnlyOperation
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.utils.asyncio import async_unsafe from django.utils.asyncio import async_unsafe
@ -11,6 +12,18 @@ from django.utils.asyncio import async_unsafe
from .models import SimpleModel 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') @skipIf(sys.platform == 'win32' and (3, 8, 0) < sys.version_info < (3, 8, 1), 'https://bugs.python.org/issue38563')
class DatabaseConnectionTest(SimpleTestCase): class DatabaseConnectionTest(SimpleTestCase):
"""A database connection cannot be used in an async context.""" """A database connection cannot be used in an async context."""