Web: don't update the status cache more than once

Once the cache expires, if multiple requestors are requesting
the status info, they all might submit gearman jobs to request
an updated status.  Instead, surround the cache check/update
with a lock so that once it expires, the first request submits
the job, all subsequent requests wait for the response and then
return the newly cached data.

Change-Id: Ifb3bfe2fe2fe5e179e53d05409897e2955a2797e
This commit is contained in:
James E. Blair
2018-09-25 14:55:47 -07:00
parent 507be8c5bf
commit 824ca389b8

View File

@@ -200,6 +200,7 @@ class ZuulWebAPI(object):
self.cache_time = {}
self.cache_expiry = 1
self.static_cache_expiry = zuulweb.static_cache_expiry
self.status_lock = threading.Lock()
@cherrypy.expose
@cherrypy.tools.json_out(content_type='application/json; charset=utf-8')
@@ -234,12 +235,13 @@ class ZuulWebAPI(object):
return ret
def _getStatus(self, tenant):
if tenant not in self.cache or \
(time.time() - self.cache_time[tenant]) > self.cache_expiry:
job = self.rpc.submitJob('zuul:status_get',
{'tenant': tenant})
self.cache[tenant] = json.loads(job.data[0])
self.cache_time[tenant] = time.time()
with self.status_lock:
if tenant not in self.cache or \
(time.time() - self.cache_time[tenant]) > self.cache_expiry:
job = self.rpc.submitJob('zuul:status_get',
{'tenant': tenant})
self.cache[tenant] = json.loads(job.data[0])
self.cache_time[tenant] = time.time()
payload = self.cache[tenant]
if payload.get('code') == 404:
raise cherrypy.HTTPError(404, payload['message'])