summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-11-29 09:59:40 +0000
committerGerrit Code Review <review@openstack.org>2018-11-29 09:59:40 +0000
commit103e64ce24545a9c438c309640b6c83812547b24 (patch)
tree0d618ff1569313e733925ceb347583ef141e5c77
parent1aac1cc8d2df28979a70808fe470228cdf5dd401 (diff)
parent6eb80deb36ba3f1c6975ce321ef1c391905b661e (diff)
Merge "Add second level cache to node requests"
-rwxr-xr-xnodepool/zk.py71
1 files changed, 58 insertions, 13 deletions
diff --git a/nodepool/zk.py b/nodepool/zk.py
index 6ce42e4..d67342c 100755
--- a/nodepool/zk.py
+++ b/nodepool/zk.py
@@ -703,6 +703,7 @@ class ZooKeeper(object):
703 self._node_cache = None 703 self._node_cache = None
704 self._request_cache = None 704 self._request_cache = None
705 self._cached_nodes = {} 705 self._cached_nodes = {}
706 self._cached_node_requests = {}
706 707
707 # ======================================================================= 708 # =======================================================================
708 # Private Methods 709 # Private Methods
@@ -899,6 +900,8 @@ class ZooKeeper(object):
899 self._node_cache.start() 900 self._node_cache.start()
900 901
901 self._request_cache = TreeCache(self.client, self.REQUEST_ROOT) 902 self._request_cache = TreeCache(self.client, self.REQUEST_ROOT)
903 self._request_cache.listen_fault(self.cacheFaultListener)
904 self._request_cache.listen(self.requestCacheListener)
902 self._request_cache.start() 905 self._request_cache.start()
903 906
904 def disconnect(self): 907 def disconnect(self):
@@ -1569,25 +1572,21 @@ class ZooKeeper(object):
1569 1572
1570 :returns: The request data, or None if the request was not found. 1573 :returns: The request data, or None if the request was not found.
1571 ''' 1574 '''
1572 path = self._requestPath(request)
1573 data = None
1574 stat = None
1575 if cached: 1575 if cached:
1576 cached_data = self._request_cache.get_data(path) 1576 d = self._cached_node_requests.get(request)
1577 if cached_data: 1577 if d:
1578 data = cached_data.data 1578 return d
1579 stat = cached_data.stat
1580 1579
1581 # If data is empty we either didn't use the cache or the cache didn't 1580 # If we got here we either didn't use the cache or the cache didn't
1582 # have the request (yet). Note that even if we use caching we need to 1581 # have the request (yet). Note that even if we use caching we need to
1583 # do a real query if the cached data is empty because the request data 1582 # do a real query if the cached data is empty because the request data
1584 # might not be in the cache yet when it's listed by the get_children 1583 # might not be in the cache yet when it's listed by the get_children
1585 # call. 1584 # call.
1586 if not data: 1585 try:
1587 try: 1586 path = self._requestPath(request)
1588 data, stat = self.client.get(path) 1587 data, stat = self.client.get(path)
1589 except kze.NoNodeError: 1588 except kze.NoNodeError:
1590 return None 1589 return None
1591 1590
1592 d = NodeRequest.fromDict(self._bytesToDict(data), request) 1591 d = NodeRequest.fromDict(self._bytesToDict(data), request)
1593 d.stat = stat 1592 d.stat = stat
@@ -2107,3 +2106,49 @@ class ZooKeeper(object):
2107 except KeyError: 2106 except KeyError:
2108 # If it's already gone, don't care 2107 # If it's already gone, don't care
2109 pass 2108 pass
2109
2110 def requestCacheListener(self, event):
2111
2112 if hasattr(event.event_data, 'path'):
2113 # Ignore root node
2114 path = event.event_data.path
2115 if path == self.REQUEST_ROOT:
2116 return
2117
2118 # Ignore lock nodes
2119 if '/lock' in path:
2120 return
2121
2122 # Ignore any non-node related events such as connection events here
2123 if event.event_type not in (TreeEvent.NODE_ADDED,
2124 TreeEvent.NODE_UPDATED,
2125 TreeEvent.NODE_REMOVED):
2126 return
2127
2128 path = event.event_data.path
2129 request_id = path.rsplit('/', 1)[1]
2130
2131 if event.event_type in (TreeEvent.NODE_ADDED, TreeEvent.NODE_UPDATED):
2132 # Perform an in-place update of the cached request if possible
2133 d = self._bytesToDict(event.event_data.data)
2134 old_request = self._cached_node_requests.get(request_id)
2135 if old_request:
2136 if event.event_data.stat.version <= old_request.stat.version:
2137 # Don't update to older data
2138 return
2139 if old_request.lock:
2140 # Don't update a locked node request
2141 return
2142 old_request.updateFromDict(d)
2143 old_request.stat = event.event_data.stat
2144 else:
2145 request = NodeRequest.fromDict(d, request_id)
2146 request.stat = event.event_data.stat
2147 self._cached_node_requests[request_id] = request
2148
2149 elif event.event_type == TreeEvent.NODE_REMOVED:
2150 try:
2151 del self._cached_node_requests[request_id]
2152 except KeyError:
2153 # If it's already gone, don't care
2154 pass