Skip to content

Commit

Permalink
[FIX] website: prevent SQL deadlock with website.visitor
Browse files Browse the repository at this point in the history
Since it's first implementation at [1], a new cursor is created to then
build a new environment after the website's `authenticate` overide with
the new `uid` of the logged in user.

Since the new visitor SQL upsert refactoring done at [2], it seems to be
introducing a SQL deadlock sometimes.
It has been detected on odoo.com while monitoring the logs. Despite
being quite rare, it still happens too often due to our heavy trafic.

Step to reproduce (among others):
- Install website_livechat
- Login as admin on 127.0.0.1
- On 127.0.0.2, load the website
- Open the livechat
- Type something in the discussion
- Directly try to login as admin
- It will load for a certain time then crash on a 502 timeout due to the
  SQL deadlock
- You may need to repeat the process to actually face the bug

[1]: odoo@6bec0e4
[2]: odoo@d348bed

closes odoo#109746

Signed-off-by: Olivier Dony (odo) <[email protected]>
  • Loading branch information
rdeodoo committed Jan 12, 2023
1 parent 64c5c32 commit b241cf7
Showing 1 changed file with 14 additions and 15 deletions.
29 changes: 14 additions & 15 deletions addons/website/models/res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,18 @@ def authenticate(cls, db, login, password, user_agent_env):
visitor_pre_authenticate_sudo = request.env['website.visitor']._get_visitor_from_request()
uid = super(ResUsers, cls).authenticate(db, login, password, user_agent_env)
if uid and visitor_pre_authenticate_sudo:
with cls.pool.cursor() as cr:
env = api.Environment(cr, uid, {})
user_partner = env.user.partner_id
visitor_current_user_sudo = env['website.visitor'].sudo().search([
('partner_id', '=', user_partner.id)
], limit=1)
if visitor_current_user_sudo:
# A visitor exists for the logged in user, link public
# visitor records to it.
if visitor_pre_authenticate_sudo != visitor_current_user_sudo:
visitor_pre_authenticate_sudo._merge_visitor(visitor_current_user_sudo)
visitor_current_user_sudo._update_visitor_last_visit()
else:
visitor_pre_authenticate_sudo.access_token = user_partner.id
visitor_pre_authenticate_sudo._update_visitor_last_visit()
env = api.Environment(request.env.cr, uid, {})
user_partner = env.user.partner_id
visitor_current_user_sudo = env['website.visitor'].sudo().search([
('partner_id', '=', user_partner.id)
], limit=1)
if visitor_current_user_sudo:
# A visitor exists for the logged in user, link public
# visitor records to it.
if visitor_pre_authenticate_sudo != visitor_current_user_sudo:
visitor_pre_authenticate_sudo._merge_visitor(visitor_current_user_sudo)
visitor_current_user_sudo._update_visitor_last_visit()
else:
visitor_pre_authenticate_sudo.access_token = user_partner.id
visitor_pre_authenticate_sudo._update_visitor_last_visit()
return uid

0 comments on commit b241cf7

Please sign in to comment.