summaryrefslogtreecommitdiff
path: root/addons/website/models
diff options
context:
space:
mode:
authorJeremy Kersten <jke@odoo.com>2020-08-26 10:38:50 +0000
committerJeremy Kersten <jke@odoo.com>2020-08-28 13:12:38 +0000
commit98e12901c97a67dc87f21647473754cd6f384d4a (patch)
tree48d924a2702704fc56a4c7dc078dbd5de959abe8 /addons/website/models
parent67da65cf77338d4e110e0a5edc3dd4cbf411f753 (diff)
[FIX] website: invalide cache page with classic ormcache invalidation
To avoid to manually invalid the lru cache and probably miss some place (assets, website menu, qweb view, website, company, ...) we use the classic cache. Courtesy of @rco-odoo for the help and review closes odoo/odoo#56572 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Diffstat (limited to 'addons/website/models')
-rw-r--r--addons/website/models/ir_http.py20
-rw-r--r--addons/website/models/website_page.py18
2 files changed, 22 insertions, 16 deletions
diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py
index 53762ac85c3..ebda40a665a 100644
--- a/addons/website/models/ir_http.py
+++ b/addons/website/models/ir_http.py
@@ -19,7 +19,6 @@ from odoo import registry, SUPERUSER_ID
from odoo.http import request
from odoo.tools.safe_eval import safe_eval
from odoo.osv.expression import FALSE_DOMAIN
-from odoo.tools.lru import LRU
from odoo.addons.http_routing.models.ir_http import ModelConverter, _guess_mimetype
from odoo.addons.portal.controllers.portal import _build_url_w_params
@@ -70,7 +69,6 @@ class Http(models.AbstractModel):
@classmethod
def clear_caches(cls):
super(Http, cls)._clear_routing_map()
- cls.clear_cached_pages()
return super(Http, cls).clear_caches()
@classmethod
@@ -244,10 +242,6 @@ class Http(models.AbstractModel):
return mods + [mod for mod in installed if mod.startswith('website')]
@classmethod
- def clear_cached_pages(cls):
- cls._cached_pages = LRU(1024)
-
- @classmethod
def _serve_page(cls):
req_page = request.httprequest.path
page_domain = [('url', '=', req_page)] + request.website.website_domain()
@@ -268,22 +262,17 @@ class Http(models.AbstractModel):
and request.httprequest.method == "GET"
and request.env.user._is_public() # only cache for unlogged user
and 'nocache' not in request.params # allow bypass cache / debug
+ and not request.session.debug
and len(cache_key) and cache_key[-1] is not None # nocache via expr
):
need_to_cache = True
- if not hasattr(cls, '_cached_pages'):
- cls.clear_cached_pages() # init LRU
-
- # use cached version
try:
- r = cls._cached_pages[cache_key]
+ r = page._get_cache_response(cache_key)
if r['time'] + page.cache_time > time.time():
response = werkzeug.Response(r['content'], mimetype=r['contenttype'])
response._cached_template = r['template']
response._cached_page = page
return response
- else:
- cls._cached_pages[cache_key]
except KeyError:
pass
@@ -295,13 +284,12 @@ class Http(models.AbstractModel):
if need_to_cache and response.status_code == 200:
r = response.render()
- cls._cached_pages[cache_key] = {
+ page._set_cache_response(cache_key, {
'content': r,
'contenttype': response.headers['Content-Type'],
'time': time.time(),
'template': getattr(response, 'qcontext', {}).get('response_template')
- }
-
+ })
return response
return False
diff --git a/addons/website/models/website_page.py b/addons/website/models/website_page.py
index 96eed5a06ee..d5da26d8cfa 100644
--- a/addons/website/models/website_page.py
+++ b/addons/website/models/website_page.py
@@ -201,6 +201,7 @@ class Page(models.Model):
def write(self, vals):
if 'url' in vals and not vals['url'].startswith('/'):
vals['url'] = '/' + vals['url']
+ self.clear_caches() # write on page == write on view that invalid cache
return super(Page, self).write(vals)
def get_website_meta(self):
@@ -215,3 +216,20 @@ class Page(models.Model):
if self.cache_key_expr: # e.g. (request.session.geoip.get('country_code'),)
cache_key += safe_eval(self.cache_key_expr, {'request': req})
return cache_key
+
+ def _get_cache_response(self, cache_key):
+ """ Return the cached response corresponding to ``self`` and ``cache_key``.
+ Raise a KeyError if the item is not in cache.
+ """
+ # HACK: we use the same LRU as ormcache to take advantage from its
+ # distributed invalidation, but we don't explicitly use ormcache
+ return self.pool._Registry__cache[('website.page', _cached_response, self.id, cache_key)]
+
+ def _set_cache_response(self, cache_key, response):
+ """ Put in cache the given response. """
+ self.pool._Registry__cache[('website.page', _cached_response, self.id, cache_key)] = response
+
+
+# this is just a dummy function to be used as ormcache key
+def _cached_response():
+ pass