Used a regular lock for app registry population.
Since the app registry is always populated before the first request is processed, the situation described in #18251 for the old app cache cannot happen any more. Refs #18251, #21628.
This commit is contained in:
parent
3777390713
commit
d06997df35
|
@ -1,11 +1,11 @@
|
||||||
from collections import Counter, defaultdict, OrderedDict
|
from collections import Counter, defaultdict, OrderedDict
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils import lru_cache
|
from django.utils import lru_cache
|
||||||
from django.utils.module_loading import import_lock
|
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
|
||||||
from .base import AppConfig
|
from .base import AppConfig
|
||||||
|
@ -44,6 +44,9 @@ class Apps(object):
|
||||||
# Whether the registry is populated.
|
# Whether the registry is populated.
|
||||||
self.ready = False
|
self.ready = False
|
||||||
|
|
||||||
|
# Lock for thread-safe population.
|
||||||
|
self._lock = threading.Lock()
|
||||||
|
|
||||||
# Pending lookups for lazy relations.
|
# Pending lookups for lazy relations.
|
||||||
self._pending_lookups = {}
|
self._pending_lookups = {}
|
||||||
|
|
||||||
|
@ -61,10 +64,10 @@ class Apps(object):
|
||||||
"""
|
"""
|
||||||
if self.ready:
|
if self.ready:
|
||||||
return
|
return
|
||||||
# Since populate() may be a side effect of imports, and since it will
|
|
||||||
# itself import modules, an ABBA deadlock between threads would be
|
# populate() might be called by two threads in parallel on servers
|
||||||
# possible if we didn't take the import lock. See #18251.
|
# that create threads before initializing the WSGI callable.
|
||||||
with import_lock():
|
with self._lock:
|
||||||
if self.ready:
|
if self.ready:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from __future__ import absolute_import # Avoid importing `importlib` from this package.
|
from __future__ import absolute_import # Avoid importing `importlib` from this package.
|
||||||
|
|
||||||
from contextlib import contextmanager
|
|
||||||
import copy
|
import copy
|
||||||
import imp
|
import imp
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
@ -36,18 +35,6 @@ def import_by_path(dotted_path, error_prefix=''):
|
||||||
return attr
|
return attr
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def import_lock():
|
|
||||||
"""
|
|
||||||
Context manager that aquires the import lock.
|
|
||||||
"""
|
|
||||||
imp.acquire_lock()
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
imp.release_lock()
|
|
||||||
|
|
||||||
|
|
||||||
def autodiscover_modules(*args, **kwargs):
|
def autodiscover_modules(*args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Auto-discover INSTALLED_APPS modules and fail silently when
|
Auto-discover INSTALLED_APPS modules and fail silently when
|
||||||
|
|
Loading…
Reference in New Issue