From c8243e71c6da37547a19f61c58f25d5d03e13d38 Mon Sep 17 00:00:00 2001 From: Toufik Benjaa Date: Wed, 21 Mar 2018 19:36:19 +0100 Subject: [PATCH] [FIX] http: Consume less cursors for session checks - Each time we check if a session is valid we create a new cursor. This could lead to issues with db_maxconn that limits the number of connections to the postgresql server. In a perfect world, a worker should use a single connection to postgres to process the request. The only known side effect is that the cursor is created earlier in the execution of the code. - This commit fixes issues with the longpolling raising Psycopg2.PoolError exceptions on databases with a lot of clients. --- odoo/http.py | 10 ++++++---- odoo/service/security.py | 20 +++++++++----------- odoo/tests/common.py | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/odoo/http.py b/odoo/http.py index 84298c20a63..0075b1bed34 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1047,7 +1047,7 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.db = db self.uid = uid self.login = login - self.session_token = uid and security.compute_session_token(self) + self.session_token = uid and security.compute_session_token(self, request.env) request.uid = uid request.disable_db = False @@ -1062,15 +1062,17 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): """ if not self.db or not self.uid: raise SessionExpiredException("Session expired") - + # We create our own environment instead of the request's one. + # to avoid creating it without the uid since request.uid isn't set yet + env = odoo.api.Environment(request.cr, self.uid, self.context) # == BACKWARD COMPATIBILITY TO CONVERT OLD SESSION TYPE TO THE NEW ONES ! REMOVE ME AFTER 11.0 == if self.get('password'): security.check(self.db, self.uid, self.password) - self.session_token = security.compute_session_token(self) + self.session_token = security.compute_session_token(self, env) self.pop('password') # ================================================================================================= # here we check if the session is still valid - if not security.check_session(self): + if not security.check_session(self, env): raise SessionExpiredException("Session expired") def logout(self, keep_db=False): diff --git a/odoo/service/security.py b/odoo/service/security.py index 229e4b84077..54d108fb4b1 100644 --- a/odoo/service/security.py +++ b/odoo/service/security.py @@ -12,15 +12,13 @@ def check(db, uid, passwd): res_users = odoo.registry(db)['res.users'] return res_users.check(db, uid, passwd) -def compute_session_token(session): - with odoo.registry(session.db).cursor() as cr: - self = odoo.api.Environment(cr, session.uid, {})['res.users'].browse(session.uid) - return self._compute_session_token(session.sid) +def compute_session_token(session, env): + self = env['res.users'].browse(session.uid) + return self._compute_session_token(session.sid) -def check_session(session): - with odoo.registry(session.db).cursor() as cr: - self = odoo.api.Environment(cr, session.uid, {})['res.users'].browse(session.uid) - if odoo.tools.misc.consteq(self._compute_session_token(session.sid), session.session_token): - return True - self._invalidate_session_cache() - return False +def check_session(session, env): + self = env['res.users'].browse(session.uid) + if odoo.tools.misc.consteq(self._compute_session_token(session.sid), session.session_token): + return True + self._invalidate_session_cache() + return False diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 37000441306..5c88da20e57 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -288,7 +288,7 @@ class HttpCase(TransactionCase): session.db = db session.uid = uid session.login = user - session.session_token = uid and security.compute_session_token(session) + session.session_token = uid and security.compute_session_token(session, env) session.context = env['res.users'].context_get() or {} session.context['uid'] = uid session._fix_lang(session.context)