Allow cachedproperty to avoid locking
Under some cirumstances it is ok to recompute a value when raced to by multiple threads, for these cases allow the cachedproperty to avoid needing and using a lock. Change-Id: Icb71cb5ea280185cfb120671be900435dabcd50b
This commit is contained in:
@@ -350,8 +350,11 @@ class cachedproperty(object):
|
|||||||
cached property would be stored under '_get_thing' in the self object
|
cached property would be stored under '_get_thing' in the self object
|
||||||
after the first call to 'get_thing' occurs.
|
after the first call to 'get_thing' occurs.
|
||||||
"""
|
"""
|
||||||
def __init__(self, fget):
|
def __init__(self, fget=None, require_lock=True):
|
||||||
self._lock = threading.RLock()
|
if require_lock:
|
||||||
|
self._lock = threading.RLock()
|
||||||
|
else:
|
||||||
|
self._lock = None
|
||||||
# If a name is provided (as an argument) then this will be the string
|
# If a name is provided (as an argument) then this will be the string
|
||||||
# to place the cached attribute under if not then it will be the
|
# to place the cached attribute under if not then it will be the
|
||||||
# function itself to be wrapped into a property.
|
# function itself to be wrapped into a property.
|
||||||
@@ -365,10 +368,12 @@ class cachedproperty(object):
|
|||||||
self.__doc__ = None
|
self.__doc__ = None
|
||||||
|
|
||||||
def __call__(self, fget):
|
def __call__(self, fget):
|
||||||
# If __init__ received a string then this will be the function to be
|
# If __init__ received a string or a lock boolean then this will be
|
||||||
# wrapped as a property (if __init__ got a function then this will not
|
# the function to be wrapped as a property (if __init__ got a
|
||||||
# be called).
|
# function then this will not be called).
|
||||||
self._fget = fget
|
self._fget = fget
|
||||||
|
if not self._attr_name:
|
||||||
|
self._attr_name = "_%s" % (fget.__name__)
|
||||||
self.__doc__ = getattr(fget, '__doc__', None)
|
self.__doc__ = getattr(fget, '__doc__', None)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@@ -387,13 +392,17 @@ class cachedproperty(object):
|
|||||||
if hasattr(instance, self._attr_name):
|
if hasattr(instance, self._attr_name):
|
||||||
return getattr(instance, self._attr_name)
|
return getattr(instance, self._attr_name)
|
||||||
else:
|
else:
|
||||||
with self._lock:
|
if self._lock is not None:
|
||||||
try:
|
self._lock.acquire()
|
||||||
return getattr(instance, self._attr_name)
|
try:
|
||||||
except AttributeError:
|
return getattr(instance, self._attr_name)
|
||||||
value = self._fget(instance)
|
except AttributeError:
|
||||||
setattr(instance, self._attr_name, value)
|
value = self._fget(instance)
|
||||||
return value
|
setattr(instance, self._attr_name, value)
|
||||||
|
return value
|
||||||
|
finally:
|
||||||
|
if self._lock is not None:
|
||||||
|
self._lock.release()
|
||||||
|
|
||||||
|
|
||||||
def millis_to_datetime(milliseconds):
|
def millis_to_datetime(milliseconds):
|
||||||
|
|||||||
Reference in New Issue
Block a user