Make Provider overriding methods thread safe

This commit is contained in:
Roman Mogilatov 2017-04-18 23:30:29 +03:00
parent 9ed806b0ca
commit 2a9b14cb0e
5 changed files with 3341 additions and 2710 deletions

View File

@ -10,6 +10,9 @@ follows `Semantic versioning`_
Development version Development version
------------------- -------------------
.. - No features. .. - No features.
- Make ``Provider`` overriding methods thread safe:
``Provider.override(provider)``, ``Provider.reset_last_overriding()``,
``Provider.reset_override()``.
- Refactor storage locking of ``ThreadSafeSingleton`` provider. - Refactor storage locking of ``ThreadSafeSingleton`` provider.
3.4.1 3.4.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@ cimport cython
cdef class Provider(object): cdef class Provider(object):
cdef tuple __overridden cdef tuple __overridden
cdef Provider __last_overriding cdef Provider __last_overriding
cdef object __overriding_lock
cpdef object _provide(self, tuple args, dict kwargs) cpdef object _provide(self, tuple args, dict kwargs)

View File

@ -74,10 +74,17 @@ cdef class Provider(object):
__IS_PROVIDER__ = True __IS_PROVIDER__ = True
overriding_lock = threading.RLock()
"""Storage reentrant lock.
:type: :py:class:`threading.RLock`
"""
def __init__(self): def __init__(self):
"""Initializer.""" """Initializer."""
self.__overridden = tuple() self.__overridden = tuple()
self.__last_overriding = None self.__last_overriding = None
self.__overriding_lock = self.__class__.overriding_lock
super(Provider, self).__init__() super(Provider, self).__init__()
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
@ -119,6 +126,7 @@ cdef class Provider(object):
@property @property
def overridden(self): def overridden(self):
"""Return tuple of overriding providers.""" """Return tuple of overriding providers."""
with self.__overriding_lock:
return self.__overridden return self.__overridden
def override(self, provider): def override(self, provider):
@ -139,6 +147,7 @@ cdef class Provider(object):
if not is_provider(provider): if not is_provider(provider):
provider = Object(provider) provider = Object(provider)
with self.__overriding_lock:
self.__overridden += (provider,) self.__overridden += (provider,)
self.__last_overriding = provider self.__last_overriding = provider
@ -152,6 +161,7 @@ cdef class Provider(object):
:rtype: None :rtype: None
""" """
with self.__overriding_lock:
if len(self.__overridden) == 0: if len(self.__overridden) == 0:
raise Error('Provider {0} is not overridden'.format(str(self))) raise Error('Provider {0} is not overridden'.format(str(self)))
@ -166,6 +176,7 @@ cdef class Provider(object):
:rtype: None :rtype: None
""" """
with self.__overriding_lock:
self.__overridden = tuple() self.__overridden = tuple()
self.__last_overriding = None self.__last_overriding = None