From 10aa098e505e44b6a99238c2a9cd2071fd218e76 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Sat, 1 Oct 2016 11:45:03 +0200 Subject: [PATCH] add a layer of cache using x-combo-page-id for remote templates --- hobo/context_processors.py | 47 +++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/hobo/context_processors.py b/hobo/context_processors.py index 31bb8ba..563e0b0 100644 --- a/hobo/context_processors.py +++ b/hobo/context_processors.py @@ -30,28 +30,39 @@ def template_vars(request): template_vars.update({'statics_hash': statics_hash.hexdigest()}) return template_vars + class RemoteTemplate(object): def __init__(self, source): self.source = source @property def cache_key(self): - return hashlib.md5(urlparse.urlunparse( - urlparse.urlparse(self.source)[:3] + ('', '', ''))).hexdigest() + return hashlib.md5(urlparse.urlunparse( + urlparse.urlparse(self.source)[:3] + ('', '', ''))).hexdigest() def get_template(self): - item = cache.get(self.cache_key) - if item is None: + x_combo_page_id = cache.get(self.cache_key) + if x_combo_page_id is None: template_body = self.update_content() if template_body is None: raise Exception('Failed to retrieve theme') else: - template_body, expiry_time = item - if expiry_time < datetime.datetime.now(): - # stale value, put it back into the cache for other consumers and - # update the content in a different thread - self.cache(template_body) - threading.Thread(target=self.update_content).start() + combo_page_id, combo_page_id_expiry_time = x_combo_page_id + + item = cache.get(self.combo_page_id_cache_key(combo_page_id)) + if item is None: + template_body = self.update_content() + if template_body is None: + raise Exception('Failed to retrieve theme') + else: + template_body, expiry_time = item + if max(expiry_time, combo_page_id_expiry_time) < datetime.datetime.now(): + # stale value, put it back into the cache for other consumers and + # update the content in a different thread + # we do not put the template body back in the cache as we do not know if this + # page is going to resolve to the same X-Combo-Page-Id for this update round + self.cache(template_body, update_combo_page_id_cache=False) + threading.Thread(target=self.update_content).start() return Template(template_body) def update_content(self): @@ -59,14 +70,20 @@ class RemoteTemplate(object): if r.status_code != 200: logger.error('failed to retrieve theme') return None - self.cache(r.text) + self.cache(r.headers['x-combo-page-id'], r.text) return r.text - def cache(self, template_body): + def combo_page_id_cache_key(self, combo_page_id): + return hashlib.md5('combo-page-id-' + combo_page_id).hexdigest() + + def cache(self, combo_page_id, template_body, update_combo_page_id_cache=True): expiry_time = datetime.datetime.now() + datetime.timedelta(seconds=CACHE_REFRESH_TIMEOUT) - cache.set(self.cache_key, - (template_body, expiry_time), - 2592000) # bypass cache level expiration time + cache.set(self.cache_key, (combo_page_id, expiry_time), + 2592000) # bypass cache level expiration time + if update_combo_page_id_cache: + cache.set(self.combo_page_id_cache_key(combo_page_id), (template_body, expiry_time), + 2592000) # bypass cache level expiration time + def theme_base(request): # this context processor adds two variables to context: -- 2.1.4