odoo / odoo

Odoo. Open Source Apps To Grow Your Business.
https://www.odoo.com
Other
35.88k stars 23.34k forks source link

[BUG] Website /events view is stored in ORM cache, even though it has dynamic "Registered" banner #160621

Open elmeriniemela opened 2 months ago

elmeriniemela commented 2 months ago

Impacted versions: Reproducible at least in V16

Steps to reproduce:

  1. Setup a clean local V16 with only latest Odoo base code and ability to restart the server.

  2. install website_event

  3. Log out from the system and go to /events as a public user.

  4. register to the first event

  5. After registration, when viewing /events the green banner "Registered" is not visible even though the website visitor is registred. At this point the ORM cache has the view rendered before registration, and the view is not updated before worker restarts. image

  6. But if worker (or server) is restarted, the (ORM cache is resetted) and "Registered" banner appears. image

  7. Now the "Registered" banner is in ORM cache until the worker restarts, and website will show "Registred" for ALL public users whose request happens to hit the same worker, causing a lot of confusion for users that have not actually registered for any event.

Here is a debugged stack trace that shows method _get_cached_values of ir.qweb of being the culprit who stores the dynamic view into the worker orm cache until restart:

(Pdb) where
  /usr/lib/python3.11/threading.py(1002)_bootstrap()
-> self._bootstrap_inner()
  /usr/lib/python3.11/threading.py(1045)_bootstrap_inner()
-> self.run()
  /usr/lib/python3.11/threading.py(982)run()
-> self._target(*self._args, **self._kwargs)
  /usr/lib/python3.11/socketserver.py(691)process_request_thread()
-> self.finish_request(request, client_address)
  /usr/lib/python3.11/socketserver.py(361)finish_request()
-> self.RequestHandlerClass(request, client_address, self)
  /usr/lib/python3.11/socketserver.py(755)__init__()
-> self.handle()
  /home/elmeri/.venv/odoo16/lib/python3.11/site-packages/werkzeug/serving.py(342)handle()
-> BaseHTTPRequestHandler.handle(self)
  /usr/lib/python3.11/http/server.py(436)handle()
-> self.handle_one_request()
  /home/elmeri/.venv/odoo16/lib/python3.11/site-packages/werkzeug/serving.py(374)handle_one_request()
-> self.run_wsgi()
  /home/elmeri/.venv/odoo16/lib/python3.11/site-packages/werkzeug/serving.py(319)run_wsgi()
-> execute(self.server.app)
  /home/elmeri/.venv/odoo16/lib/python3.11/site-packages/werkzeug/serving.py(308)execute()
-> application_iter = app(environ, start_response)
  /home/elmeri/Work/16/odoo/odoo/http.py(2044)__call__()
-> response = request._serve_db()
  /home/elmeri/Work/16/odoo/odoo/http.py(1633)_serve_db()
-> return service_model.retrying(self._serve_ir_http, self.env)
  /home/elmeri/Work/16/odoo/odoo/service/model.py(133)retrying()
-> result = func()
  /home/elmeri/Work/16/odoo/odoo/http.py(1660)_serve_ir_http()
-> response = self.dispatcher.dispatch(rule.endpoint, args)
  /home/elmeri/Work/16/odoo/odoo/http.py(1774)dispatch()
-> return self.request.registry['ir.http']._dispatch(endpoint)
  /home/elmeri/Work/16/odoo/addons/website/models/ir_http.py(237)_dispatch()
-> response = super()._dispatch(endpoint)
  /home/elmeri/Work/16/odoo/odoo/addons/base/models/ir_http.py(156)_dispatch()
-> result.flatten()
  /home/elmeri/Work/16/odoo/odoo/http.py(1142)flatten()
-> self.response.append(self.render())
  /home/elmeri/Work/16/odoo/odoo/http.py(1134)render()
-> return request.env["ir.ui.view"]._render_template(self.template, self.qcontext)
  /home/elmeri/Work/16/odoo/addons/website/models/ir_ui_view.py(419)_render_template()
-> return super()._render_template(template, values=values)
  /home/elmeri/Work/16/odoo/odoo/addons/base/models/ir_ui_view.py(2127)_render_template()
-> return self.env['ir.qweb']._render(template, values)
  /home/elmeri/Work/16/odoo/odoo/tools/profiler.py(292)_tracked_method_render()
-> return method_render(self, template, values, **options)
  /home/elmeri/Work/16/odoo/odoo/addons/base/models/ir_qweb.py(581)_render()
-> result = ''.join(rendering)
  <811>(130)template_811()
  <811>(112)template_811_content()
  <811>(100)template_811_t_call_0()
  <817>(648)template_817()
  <817>(607)template_817_content()
  /home/elmeri/Work/16/odoo/odoo/addons/base/models/ir_qweb.py(2456)_load_values()
-> value = self._get_cached_values(cache_key, get_value)
  <decorator-gen-70>(2)_get_cached_values()
  /home/elmeri/Work/16/odoo/odoo/tools/cache.py(90)lookup()
-> value = d[key] = self.method(*args, **kwargs)
  /home/elmeri/Work/16/odoo/odoo/addons/base/models/ir_qweb.py(2469)_get_cached_values()
-> return get_value()
  <817>(597)template_817_t_cache_0_cache()
  <817>(154)template_817_t_cache_0()
  <817>(85)template_817_t_call_1()
  /home/elmeri/Work/16/odoo/odoo/fields.py(1210)__get__()
-> self.compute_value(recs)
  /home/elmeri/Work/16/odoo/odoo/fields.py(1392)compute_value()
-> records._compute_field_value(self)
  /home/elmeri/Work/16/odoo/addons/mail/models/mail_thread.py(403)_compute_field_value()
-> return super()._compute_field_value(field)
  /home/elmeri/Work/16/odoo/odoo/models.py(4232)_compute_field_value()
-> fields.determine(field.compute, self)
  /home/elmeri/Work/16/odoo/odoo/fields.py(98)determine()
-> return needle(*args)
> /home/elmeri/Work/16/odoo/addons/website_event/models/event_event.py(106)_compute_is_participating()
-> current_visitor = self.env['website.visitor']._get_visitor_from_request(force_create=False)
(Pdb) 
elmeriniemela commented 1 month ago

Hi @vava-odoo,

When can I expect a fix for this bug? It's a bit embarrising as random website visitors will sometimes see the "Registered" banner even though they have not even seen the event before.

vava-odoo commented 1 month ago

Hi @elmeriniemela Difficult to say, I only redirect to the related teams by tagging issues. If you have a subscription, the fast track is to open a ticket at odoo.com/help, as those get the priority. Cheers

elmeriniemela commented 1 month ago

Hi @vava-odoo

Thanks for the reply and clarification. Hopefully someone will have time to investigate this soon :)

br. Elmeri