mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-29 21:14:00 +03:00
Implement injections in thread-local and thread-safe singleton providers
This commit is contained in:
parent
6020c6caf4
commit
90a6cb3c6d
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -141,11 +141,11 @@ cdef class FactoryAggregate(Provider):
|
||||||
# Singleton providers
|
# Singleton providers
|
||||||
cdef class BaseSingleton(Provider):
|
cdef class BaseSingleton(Provider):
|
||||||
cdef Factory __instantiator
|
cdef Factory __instantiator
|
||||||
|
cdef object __storage
|
||||||
cdef bint __async
|
cdef bint __async
|
||||||
|
|
||||||
|
|
||||||
cdef class Singleton(BaseSingleton):
|
cdef class Singleton(BaseSingleton):
|
||||||
cdef object __storage
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
@ -155,7 +155,6 @@ cdef class DelegatedSingleton(Singleton):
|
||||||
|
|
||||||
|
|
||||||
cdef class ThreadSafeSingleton(BaseSingleton):
|
cdef class ThreadSafeSingleton(BaseSingleton):
|
||||||
cdef object __storage
|
|
||||||
cdef object __storage_lock
|
cdef object __storage_lock
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
@ -166,7 +165,6 @@ cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
|
||||||
|
|
||||||
|
|
||||||
cdef class ThreadLocalSingleton(BaseSingleton):
|
cdef class ThreadLocalSingleton(BaseSingleton):
|
||||||
cdef object __storage
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs)
|
cpdef object _provide(self, tuple args, dict kwargs)
|
||||||
|
|
||||||
|
|
|
@ -2077,6 +2077,12 @@ cdef class BaseSingleton(Provider):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def _async_init_instance(self, future_result, result):
|
||||||
|
instance = result.result()
|
||||||
|
self.__storage = instance
|
||||||
|
self.__async = True
|
||||||
|
future_result.set_result(instance)
|
||||||
|
|
||||||
|
|
||||||
cdef class Singleton(BaseSingleton):
|
cdef class Singleton(BaseSingleton):
|
||||||
"""Singleton provider returns same instance on every call.
|
"""Singleton provider returns same instance on every call.
|
||||||
|
@ -2124,6 +2130,8 @@ cdef class Singleton(BaseSingleton):
|
||||||
|
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
|
if __isawaitable(self.__storage):
|
||||||
|
asyncio.ensure_future(self.__storage).cancel()
|
||||||
self.__storage = None
|
self.__storage = None
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
|
@ -2147,12 +2155,6 @@ cdef class Singleton(BaseSingleton):
|
||||||
|
|
||||||
return self.__storage
|
return self.__storage
|
||||||
|
|
||||||
def _async_init_instance(self, future_result, result):
|
|
||||||
instance = result.result()
|
|
||||||
self.__storage = instance
|
|
||||||
self.__async = True
|
|
||||||
future_result.set_result(instance)
|
|
||||||
|
|
||||||
|
|
||||||
cdef class DelegatedSingleton(Singleton):
|
cdef class DelegatedSingleton(Singleton):
|
||||||
"""Delegated singleton is injected "as is".
|
"""Delegated singleton is injected "as is".
|
||||||
|
@ -2201,18 +2203,35 @@ cdef class ThreadSafeSingleton(BaseSingleton):
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
with self.__storage_lock:
|
with self.__storage_lock:
|
||||||
|
if __isawaitable(self.__storage):
|
||||||
|
asyncio.ensure_future(self.__storage).cancel()
|
||||||
self.__storage = None
|
self.__storage = None
|
||||||
|
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
"""Return single instance."""
|
"""Return single instance."""
|
||||||
storage = self.__storage
|
instance = self.__storage
|
||||||
if storage is None:
|
|
||||||
|
if instance is None:
|
||||||
with self.__storage_lock:
|
with self.__storage_lock:
|
||||||
if self.__storage is None:
|
if self.__storage is None:
|
||||||
self.__storage = __factory_call(self.__instantiator,
|
instance = __factory_call(self.__instantiator, args, kwargs)
|
||||||
args, kwargs)
|
|
||||||
storage = self.__storage
|
if __isawaitable(instance):
|
||||||
return storage
|
future_result = asyncio.Future()
|
||||||
|
instance = asyncio.ensure_future(instance)
|
||||||
|
instance.add_done_callback(functools.partial(self._async_init_instance, future_result))
|
||||||
|
self.__storage = future_result
|
||||||
|
return future_result
|
||||||
|
|
||||||
|
self.__storage = instance
|
||||||
|
|
||||||
|
if self.__async:
|
||||||
|
result = asyncio.Future()
|
||||||
|
result.set_result(instance)
|
||||||
|
return result
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
|
cdef class DelegatedThreadSafeSingleton(ThreadSafeSingleton):
|
||||||
|
@ -2270,6 +2289,8 @@ cdef class ThreadLocalSingleton(BaseSingleton):
|
||||||
|
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
|
if __isawaitable(self.__storage.instance):
|
||||||
|
asyncio.ensure_future(self.__storage.instance).cancel()
|
||||||
del self.__storage.instance
|
del self.__storage.instance
|
||||||
|
|
||||||
cpdef object _provide(self, tuple args, dict kwargs):
|
cpdef object _provide(self, tuple args, dict kwargs):
|
||||||
|
@ -2280,10 +2301,28 @@ cdef class ThreadLocalSingleton(BaseSingleton):
|
||||||
instance = self.__storage.instance
|
instance = self.__storage.instance
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
instance = __factory_call(self.__instantiator, args, kwargs)
|
instance = __factory_call(self.__instantiator, args, kwargs)
|
||||||
|
|
||||||
|
if __isawaitable(instance):
|
||||||
|
future_result = asyncio.Future()
|
||||||
|
instance = asyncio.ensure_future(instance)
|
||||||
|
instance.add_done_callback(functools.partial(self._async_init_instance, future_result))
|
||||||
|
self.__storage.instance = future_result
|
||||||
|
return future_result
|
||||||
|
|
||||||
self.__storage.instance = instance
|
self.__storage.instance = instance
|
||||||
finally:
|
finally:
|
||||||
|
if self.__async:
|
||||||
|
result = asyncio.Future()
|
||||||
|
result.set_result(instance)
|
||||||
|
return result
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
def _async_init_instance(self, future_result, result):
|
||||||
|
instance = result.result()
|
||||||
|
self.__storage.instance = instance
|
||||||
|
self.__async = True
|
||||||
|
future_result.set_result(instance)
|
||||||
|
|
||||||
|
|
||||||
cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
|
cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton):
|
||||||
"""Delegated thread-local singleton is injected "as is".
|
"""Delegated thread-local singleton is injected "as is".
|
||||||
|
|
Loading…
Reference in New Issue
Block a user