Merge lp:~openerp-dev/openobject-server/6.0-opw-576744-rha into lp:openobject-server/6.0

Proposed by Rifakat Husen (OpenERP)
Status: Merged
Merged at revision: 3634
Proposed branch: lp:~openerp-dev/openobject-server/6.0-opw-576744-rha
Merge into: lp:openobject-server/6.0
Diff against target: 46 lines (+26/-5)
1 file modified
bin/addons/base/res/res_user.py (+26/-5)
To merge this branch: bzr merge lp:~openerp-dev/openobject-server/6.0-opw-576744-rha
Reviewer Review Type Date Requested Status
Olivier Dony (Odoo) Pending
Review via email: mp+117371@code.launchpad.net

Description of the change

Hello,

It doesn't let any user to login when MRP scheduler is running through cron job(ir.cron).
If user's row is currently aquire by scheduler then login() will not go through and prevents
updating the last login date, it's simpler to try to get the lock and if that fails, we skip
the login date update for once, that's no big deal.

It's a backport of server r4049, <email address hidden>

Regards,
Rifakat Haradwala

To post a comment you must log in.
Revision history for this message
Olivier Dony (Odoo) (odo-openerp) wrote :

Looks good to me, but as this does not seem to fix the problem for the customer, I suggest we avoid the risk of merging it until we find the proper fix. Marking as rejected to avoid clustering the lists on Launchpad, feel free to reset the status if we later need it.
Thanks,

3634. By Olivier Dony (Odoo)

[FIX] res_users: improve behavior when user record is locked during login

Avoid logging an ugly and frightening traceback,
plus properly rollback the failed transaction before
continuing.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/base/res/res_user.py'
2--- bin/addons/base/res/res_user.py 2011-05-09 10:24:54 +0000
3+++ bin/addons/base/res/res_user.py 2012-08-22 15:41:20 +0000
4@@ -440,16 +440,37 @@
5 return False
6 cr = pooler.get_db(db).cursor()
7 try:
8+ # autocommit: our single request will be performed atomically.
9+ # (In this way, there is no opportunity to have two transactions
10+ # interleaving their cr.execute()..cr.commit() calls and have one
11+ # of them rolled back due to a concurrent access.)
12+ # We effectively unconditionally write the res_users line.
13+ cr.autocommit(True)
14+ # Even w/ autocommit there's a chance the user row will be locked,
15+ # in which case we can't delay the login just for the purpose of
16+ # update the last login date - hence we use FOR UPDATE NOWAIT to
17+ # try to get the lock - fail-fast
18+ cr.execute("""SELECT id from res_users
19+ WHERE login=%s AND password=%s
20+ AND active FOR UPDATE NOWAIT""",
21+ (tools.ustr(login), tools.ustr(password)), log_exceptions=False)
22 cr.execute('UPDATE res_users SET date=now() WHERE login=%s AND password=%s AND active RETURNING id',
23 (tools.ustr(login), tools.ustr(password)))
24+ except Exception:
25+ # Failing to acquire the lock on the res_users row probably means
26+ # another request is holding it - no big deal, we skip the update
27+ # for this time, and let the user login anyway.
28+ cr.rollback()
29+ cr.execute("""SELECT id from res_users
30+ WHERE login=%s AND password=%s
31+ AND active""",
32+ (tools.ustr(login), tools.ustr(password)))
33+ finally:
34 res = cr.fetchone()
35- cr.commit()
36+ cr.close()
37 if res:
38 return res[0]
39- else:
40- return False
41- finally:
42- cr.close()
43+ return False
44
45 def check_super(self, passwd):
46 if passwd == tools.config['admin_passwd']: