OLD | NEW |
(Empty) | |
| 1 from .compat import threading |
| 2 import weakref |
| 3 |
| 4 |
| 5 class NameRegistry(object): |
| 6 """Generates and return an object, keeping it as a |
| 7 singleton for a certain identifier for as long as its |
| 8 strongly referenced. |
| 9 |
| 10 e.g.:: |
| 11 |
| 12 class MyFoo(object): |
| 13 "some important object." |
| 14 def __init__(self, identifier): |
| 15 self.identifier = identifier |
| 16 |
| 17 registry = NameRegistry(MyFoo) |
| 18 |
| 19 # thread 1: |
| 20 my_foo = registry.get("foo1") |
| 21 |
| 22 # thread 2 |
| 23 my_foo = registry.get("foo1") |
| 24 |
| 25 Above, ``my_foo`` in both thread #1 and #2 will |
| 26 be *the same object*. The constructor for |
| 27 ``MyFoo`` will be called once, passing the |
| 28 identifier ``foo1`` as the argument. |
| 29 |
| 30 When thread 1 and thread 2 both complete or |
| 31 otherwise delete references to ``my_foo``, the |
| 32 object is *removed* from the :class:`.NameRegistry` as |
| 33 a result of Python garbage collection. |
| 34 |
| 35 :param creator: A function that will create a new |
| 36 value, given the identifier passed to the :meth:`.NameRegistry.get` |
| 37 method. |
| 38 |
| 39 """ |
| 40 _locks = weakref.WeakValueDictionary() |
| 41 _mutex = threading.RLock() |
| 42 |
| 43 def __init__(self, creator): |
| 44 """Create a new :class:`.NameRegistry`. |
| 45 |
| 46 |
| 47 """ |
| 48 self._values = weakref.WeakValueDictionary() |
| 49 self._mutex = threading.RLock() |
| 50 self.creator = creator |
| 51 |
| 52 def get(self, identifier, *args, **kw): |
| 53 """Get and possibly create the value. |
| 54 |
| 55 :param identifier: Hash key for the value. |
| 56 If the creation function is called, this identifier |
| 57 will also be passed to the creation function. |
| 58 :param \*args, \**kw: Additional arguments which will |
| 59 also be passed to the creation function if it is |
| 60 called. |
| 61 |
| 62 """ |
| 63 try: |
| 64 if identifier in self._values: |
| 65 return self._values[identifier] |
| 66 else: |
| 67 return self._sync_get(identifier, *args, **kw) |
| 68 except KeyError: |
| 69 return self._sync_get(identifier, *args, **kw) |
| 70 |
| 71 def _sync_get(self, identifier, *args, **kw): |
| 72 self._mutex.acquire() |
| 73 try: |
| 74 try: |
| 75 if identifier in self._values: |
| 76 return self._values[identifier] |
| 77 else: |
| 78 self._values[identifier] = value = self.creator(identifier,
*args, **kw) |
| 79 return value |
| 80 except KeyError: |
| 81 self._values[identifier] = value = self.creator(identifier, *arg
s, **kw) |
| 82 return value |
| 83 finally: |
| 84 self._mutex.release() |
OLD | NEW |