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
-------------------
.. - No features.
- Make ``Provider`` overriding methods thread safe:
``Provider.override(provider)``, ``Provider.reset_last_overriding()``,
``Provider.reset_override()``.
- Refactor storage locking of ``ThreadSafeSingleton`` provider.
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 tuple __overridden
cdef Provider __last_overriding
cdef object __overriding_lock
cpdef object _provide(self, tuple args, dict kwargs)

View File

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