summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-10-23 21:27:11 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2011-10-23 21:27:11 -0400
commitcac6e8f7890dcf53c6a243a0768ac749c4688524 (patch)
tree485069758e68d41962e4f20103b1eaefd4c7580c /tests
parentf37b497e8d6b78553f243a09c1886cdbdc425129 (diff)
downloaddogpile-core-cac6e8f7890dcf53c6a243a0768ac749c4688524.tar.gz
- Add new "nameregistry" helper. Another fixture
derived from Beaker, this allows the ad-hoc creation of a new Dogpile lock based on a name, where all other threads calling that name at the same time will get the same Dogpile lock. Allows any number of logical "dogpile" actions to carry on concurrently without any memory taken up outside of those operations. - To support the use case supported by nameregistry, added value_and_created_fn to dogpile.acquire(). The idea is that the value_and_created_fn can return (value, createdtime), so that the creation time of the value can come from the cache, thus eliminating the need for the dogpile lock to hang around persistently.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_nameregistry.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/tests/test_nameregistry.py b/tests/test_nameregistry.py
new file mode 100644
index 0000000..8d2859d
--- /dev/null
+++ b/tests/test_nameregistry.py
@@ -0,0 +1,58 @@
+from unittest import TestCase
+import time
+import threading
+from dogpile.nameregistry import NameRegistry
+import random
+
+import logging
+log = logging.getLogger(__name__)
+
+class NameRegistryTest(TestCase):
+
+ def test_name_registry(self):
+ success = [True]
+ num_operations = [0]
+
+ def create(identifier):
+ log.debug("Creator running for id: " + identifier)
+ return threading.Lock()
+
+ registry = NameRegistry(create)
+
+ baton = {
+ "beans":False,
+ "means":False,
+ "please":False
+ }
+
+ def do_something(name):
+ for iteration in xrange(20):
+ name = baton.keys()[random.randint(0, 2)]
+ lock = registry.get(name)
+ lock.acquire()
+ try:
+ if baton[name]:
+ success[0] = False
+ log.debug("Baton is already populated")
+ break
+ baton[name] = True
+ try:
+ time.sleep(random.random() * .01)
+ finally:
+ num_operations[0] += 1
+ baton[name] = False
+ finally:
+ lock.release()
+ log.debug("thread completed operations")
+
+ threads = []
+ for id_ in range(1, 20):
+ t = threading.Thread(target=do_something, args=("somename",))
+ t.start()
+ threads.append(t)
+
+ for t in threads:
+ t.join()
+
+ assert success[0]
+