Use opened connections as much as possible
instead of opening a new internal connection to set the session cookie or
retrieve the session data, which may exhaust the connection pools.
--- a/pyramid_cubicweb/session.py Wed Jun 01 17:27:29 2016 +0200
+++ b/pyramid_cubicweb/session.py Tue Jun 28 11:03:20 2016 +0200
@@ -1,5 +1,6 @@
import warnings
import logging
+from contextlib import contextmanager
from pyramid.compat import pickle
from pyramid.session import SignedCookieSessionFactory
@@ -21,6 +22,22 @@
return wrap
+@contextmanager
+def unsafe_cnx_context_manager(request):
+ """Return a connection for use as a context manager, with security disabled
+
+ If request has an attached connection, its security will be deactived in the context manager's
+ scope, else a new internal connection is returned.
+ """
+ cnx = request.cw_cnx
+ if cnx is None:
+ with request.registry['cubicweb.repository'].internal_cnx() as cnx:
+ yield cnx
+ else:
+ with cnx.security_enabled(read=False, write=False):
+ yield cnx
+
+
def CWSessionFactory(
secret,
cookie_name='session',
@@ -95,7 +112,7 @@
if self._loaded:
return
- with self.repo.internal_cnx() as cnx:
+ with unsafe_cnx_context_manager(self.request) as cnx:
value_rset = cnx.execute('Any D WHERE X eid %(x)s, X cwsessiondata D',
{'x': self.sessioneid})
value = value_rset[0][0]
@@ -117,7 +134,7 @@
data = Binary(pickle.dumps(dict(self)))
sessioneid = self.sessioneid
- with self.repo.internal_cnx() as cnx:
+ with unsafe_cnx_context_manager(self.request) as cnx:
if not sessioneid:
session = cnx.create_entity(
'CWSession', cwsessiondata=data)