summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Bean <rbean@redhat.com>2013-01-02 10:35:42 -0500
committerRalph Bean <rbean@redhat.com>2013-01-02 10:35:42 -0500
commitfdface8b8dc29e389ccdd6c5daf80014fc4d4eb2 (patch)
tree82d28c73927181cd1f07229b2622c6548ed61aa4
parent368746752ee27029ebe059fd6dd550b8ad4ce23c (diff)
downloaddogpile-core-fdface8b8dc29e389ccdd6c5daf80014fc4d4eb2.tar.gz
Allow creation of new values by a background thread.
-rw-r--r--dogpile/core/dogpile.py27
1 files changed, 24 insertions, 3 deletions
diff --git a/dogpile/core/dogpile.py b/dogpile/core/dogpile.py
index c892f8b..01aa274 100644
--- a/dogpile/core/dogpile.py
+++ b/dogpile/core/dogpile.py
@@ -1,5 +1,6 @@
import time
import logging
+import threading
log = logging.getLogger(__name__)
@@ -54,12 +55,14 @@ class Lock(object):
mutex,
creator,
value_and_created_fn,
- expiretime
+ expiretime,
+ threaded_creation=False,
):
self.mutex = mutex
self.creator = creator
self.value_and_created_fn = value_and_created_fn
self.expiretime = expiretime
+ self.threaded_creation = threaded_creation
def _is_expired(self, createdtime):
"""Return true if the expiration time is reached, or no
@@ -129,13 +132,31 @@ class Lock(object):
if not self._is_expired(createdtime):
log.debug("value already present")
return value, createdtime
+ elif self.threaded_creation:
+ # If configured for threaded creation, give responsibility
+ # for releasing the mutex to a new thread which will
+ # invoke the creator callable on its own time.
+ def worker():
+ try:
+ self.creator()
+ finally:
+ self.mutex.release()
+ log.debug("Released creation lock")
+
+ log.debug("spinning off value creation thread")
+ thread = threading.Thread(target=worker)
+ thread.start()
+
+ # Return the stale value while the worker works.
+ return value, createdtime
log.debug("Calling creation function")
created = self.creator()
return created
finally:
- self.mutex.release()
- log.debug("Released creation lock")
+ if not self.threaded_creation:
+ self.mutex.release()
+ log.debug("Released creation lock")
def __enter__(self):