[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.
This commit is contained in:
Toufik Benjaa
2018-06-12 18:10:37 +02:00
parent 8357e7395e
commit c8243e71c6
3 changed files with 16 additions and 16 deletions
+6 -4
View File
@@ -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):
+9 -11
View File
@@ -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
+1 -1
View File
@@ -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)