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:
Joshua Harlow
2016-02-08 23:16:58 -08:00
parent 61efc31e96
commit b033fa6722

View File

@@ -350,8 +350,11 @@ class cachedproperty(object):
cached property would be stored under '_get_thing' in the self object
after the first call to 'get_thing' occurs.
"""
def __init__(self, fget):
self._lock = threading.RLock()
def __init__(self, fget=None, require_lock=True):
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
# to place the cached attribute under if not then it will be the
# function itself to be wrapped into a property.
@@ -365,10 +368,12 @@ class cachedproperty(object):
self.__doc__ = None
def __call__(self, fget):
# If __init__ received a string then this will be the function to be
# wrapped as a property (if __init__ got a function then this will not
# be called).
# If __init__ received a string or a lock boolean then this will be
# the function to be wrapped as a property (if __init__ got a
# function then this will not be called).
self._fget = fget
if not self._attr_name:
self._attr_name = "_%s" % (fget.__name__)
self.__doc__ = getattr(fget, '__doc__', None)
return self
@@ -387,13 +392,17 @@ class cachedproperty(object):
if hasattr(instance, self._attr_name):
return getattr(instance, self._attr_name)
else:
with self._lock:
try:
return getattr(instance, self._attr_name)
except AttributeError:
value = self._fget(instance)
setattr(instance, self._attr_name, value)
return value
if self._lock is not None:
self._lock.acquire()
try:
return getattr(instance, self._attr_name)
except AttributeError:
value = self._fget(instance)
setattr(instance, self._attr_name, value)
return value
finally:
if self._lock is not None:
self._lock.release()
def millis_to_datetime(milliseconds):