diff options
| author | Jeremy Kersten <jke@odoo.com> | 2020-08-26 10:38:50 +0000 |
|---|---|---|
| committer | Jeremy Kersten <jke@odoo.com> | 2020-08-28 13:12:38 +0000 |
| commit | 98e12901c97a67dc87f21647473754cd6f384d4a (patch) | |
| tree | 48d924a2702704fc56a4c7dc078dbd5de959abe8 /addons | |
| parent | 67da65cf77338d4e110e0a5edc3dd4cbf411f753 (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')
| -rw-r--r-- | addons/website/models/ir_http.py | 20 | ||||
| -rw-r--r-- | addons/website/models/website_page.py | 18 |
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 |
