summaryrefslogtreecommitdiff
path: root/ironic/common/hash_ring.py
diff options
context:
space:
mode:
authorGregory Haynes <greg@greghaynes.net>2014-09-11 17:51:57 -0700
committerDevananda van der Veen <devananda.vdv@gmail.com>2014-09-29 15:57:55 -0700
commit9de2d21a96f440807b9822173de3fd3b6119fbe8 (patch)
tree7f2589abb11809b0d4347ee78d5dc47f6a87f73b /ironic/common/hash_ring.py
parent8a0923c437acf5bd840dc7f64db5e555962c15ac (diff)
downloadironic-9de2d21a96f440807b9822173de3fd3b6119fbe8.tar.gz
Add HashRingManager to wrap hash ring singleton
Currently, the API service creates a new hash ring on every request. Instead of that, we should cache the hash ring object -- but we should also expose a way to refresh it when necessary. This method will also be used by the ConductorManager to cache and refresh the hash ring when conductors join / leave the cluster. This patch preserves the existing API behavior by resetting the hash ring on every request. This should be addressed in a subsequent patch. Co-Authored-By: Devananda van der Veen <devananda.vdv@gmail.com> Change-Id: Ib7ab55452499d1e1c362e4cd127f1e6e38106d6c
Diffstat (limited to 'ironic/common/hash_ring.py')
-rw-r--r--ironic/common/hash_ring.py38
1 files changed, 22 insertions, 16 deletions
diff --git a/ironic/common/hash_ring.py b/ironic/common/hash_ring.py
index db3081fca..40f421424 100644
--- a/ironic/common/hash_ring.py
+++ b/ironic/common/hash_ring.py
@@ -114,10 +114,23 @@ class HashRing(object):
class HashRingManager(object):
+ _hash_rings = None
+ _lock = threading.Lock()
+
def __init__(self):
- self._lock = threading.Lock()
self.dbapi = dbapi.get_instance()
- self.hash_rings = None
+
+ @property
+ def ring(self):
+ # Hot path, no lock
+ if self._hash_rings is not None:
+ return self._hash_rings
+
+ with self._lock:
+ if self._hash_rings is None:
+ rings = self._load_hash_rings()
+ self.__class__._hash_rings = rings
+ return self._hash_rings
def _load_hash_rings(self):
rings = {}
@@ -127,21 +140,14 @@ class HashRingManager(object):
rings[driver_name] = HashRing(hosts)
return rings
- def _ensure_rings_fresh(self):
- # Hot path, no lock
- # TODO(russell_h): Consider adding time-based invalidation of rings
- if self.hash_rings is not None:
- return
-
+ @classmethod
+ def reset(self):
with self._lock:
- if self.hash_rings is None:
- self.hash_rings = self._load_hash_rings()
-
- def get_hash_ring(self, driver_name):
- self._ensure_rings_fresh()
+ self._hash_rings = None
+ def __getitem__(self, driver_name):
try:
- return self.hash_rings[driver_name]
+ return self.ring[driver_name]
except KeyError:
- raise exception.DriverNotFound(_("The driver '%s' is unknown.") %
- driver_name)
+ raise exception.DriverNotFound(
+ _("The driver '%s' is unknown.") % driver_name)