Don't create a connection on constructor

Some controllers in the sqlalchemy driver were creating connections in
their constructors. This, besides creating a connection when it's not
needed, ended up creating such connection in the wrong thread.

The above is an issue when using sqlite or non-thread-safe drivers since
the connection would be shared accross different threads when running
under scalable wsgi containers.

This patch moves the connection back to being lazy.

Change-Id: I4b45ad1b20b81962a56536fd875d165072493ade
This commit is contained in:
Flavio Percoco 2015-09-08 23:58:46 +02:00
parent ffff834edb
commit 161f5848d1
3 changed files with 23 additions and 35 deletions

View File

@ -39,23 +39,18 @@ def _match(project, queue):
class CatalogueController(base.CatalogueBase): class CatalogueController(base.CatalogueBase):
def __init__(self, *args, **kwargs):
super(CatalogueController, self).__init__(*args, **kwargs)
self._conn = self.driver.connection
def list(self, project): def list(self, project):
stmt = sa.sql.select([tables.Catalogue]).where( stmt = sa.sql.select([tables.Catalogue]).where(
tables.Catalogue.c.project == project tables.Catalogue.c.project == project
) )
cursor = self._conn.execute(stmt) cursor = self.driver.connection.execute(stmt)
return (_normalize(v) for v in cursor) return (_normalize(v) for v in cursor)
def get(self, project, queue): def get(self, project, queue):
stmt = sa.sql.select([tables.Catalogue]).where( stmt = sa.sql.select([tables.Catalogue]).where(
_match(project, queue) _match(project, queue)
) )
entry = self._conn.execute(stmt).fetchone() entry = self.driver.connection.execute(stmt).fetchone()
if entry is None: if entry is None:
raise errors.QueueNotMapped(queue, project) raise errors.QueueNotMapped(queue, project)
@ -73,7 +68,7 @@ class CatalogueController(base.CatalogueBase):
stmt = sa.sql.insert(tables.Catalogue).values( stmt = sa.sql.insert(tables.Catalogue).values(
project=project, queue=queue, pool=pool project=project, queue=queue, pool=pool
) )
self._conn.execute(stmt) self.driver.connection.execute(stmt)
except sa.exc.IntegrityError: except sa.exc.IntegrityError:
self._update(project, queue, pool) self._update(project, queue, pool)
@ -82,13 +77,13 @@ class CatalogueController(base.CatalogueBase):
stmt = sa.sql.delete(tables.Catalogue).where( stmt = sa.sql.delete(tables.Catalogue).where(
_match(project, queue) _match(project, queue)
) )
self._conn.execute(stmt) self.driver.connection.execute(stmt)
def _update(self, project, queue, pool): def _update(self, project, queue, pool):
stmt = sa.sql.update(tables.Catalogue).where( stmt = sa.sql.update(tables.Catalogue).where(
_match(project, queue) _match(project, queue)
).values(pool=pool) ).values(pool=pool)
self._conn.execute(stmt) self.driver.connection.execute(stmt)
def update(self, project, queue, pool=None): def update(self, project, queue, pool=None):
if pool is None: if pool is None:
@ -101,7 +96,7 @@ class CatalogueController(base.CatalogueBase):
def drop_all(self): def drop_all(self):
stmt = sa.sql.expression.delete(tables.Catalogue) stmt = sa.sql.expression.delete(tables.Catalogue)
self._conn.execute(stmt) self.driver.connection.execute(stmt)
def _normalize(entry): def _normalize(entry):

View File

@ -29,8 +29,6 @@ class FlavorsController(base.FlavorsBase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(FlavorsController, self).__init__(*args, **kwargs) super(FlavorsController, self).__init__(*args, **kwargs)
self._conn = self.driver.connection
self._pools_ctrl = self.driver.pools_controller self._pools_ctrl = self.driver.pools_controller
@utils.raises_conn_error @utils.raises_conn_error
@ -47,7 +45,7 @@ class FlavorsController(base.FlavorsBase):
if limit > 0: if limit > 0:
stmt = stmt.limit(limit) stmt = stmt.limit(limit)
cursor = self._conn.execute(stmt) cursor = self.driver.connection.execute(stmt)
marker_name = {} marker_name = {}
@ -66,7 +64,7 @@ class FlavorsController(base.FlavorsBase):
tables.Flavors.c.project == project) tables.Flavors.c.project == project)
) )
flavor = self._conn.execute(stmt).fetchone() flavor = self.driver.connection.execute(stmt).fetchone()
if flavor is None: if flavor is None:
raise errors.FlavorDoesNotExist(name) raise errors.FlavorDoesNotExist(name)
@ -80,7 +78,7 @@ class FlavorsController(base.FlavorsBase):
stmt = sa.sql.expression.insert(tables.Flavors).values( stmt = sa.sql.expression.insert(tables.Flavors).values(
name=name, pool=pool, project=project, capabilities=cap name=name, pool=pool, project=project, capabilities=cap
) )
self._conn.execute(stmt) self.driver.connection.execute(stmt)
except sa.exc.IntegrityError: except sa.exc.IntegrityError:
if not self._pools_ctrl.get_group(pool): if not self._pools_ctrl.get_group(pool):
raise errors.PoolDoesNotExist(pool) raise errors.PoolDoesNotExist(pool)
@ -97,7 +95,7 @@ class FlavorsController(base.FlavorsBase):
sa.and_(tables.Flavors.c.name == name, sa.and_(tables.Flavors.c.name == name,
tables.Flavors.c.project == project) tables.Flavors.c.project == project)
).limit(1) ).limit(1)
return self._conn.execute(stmt).fetchone() is not None return self.driver.connection.execute(stmt).fetchone() is not None
@utils.raises_conn_error @utils.raises_conn_error
def update(self, name, project=None, pool=None, capabilities=None): def update(self, name, project=None, pool=None, capabilities=None):
@ -117,7 +115,7 @@ class FlavorsController(base.FlavorsBase):
sa.and_(tables.Flavors.c.name == name, sa.and_(tables.Flavors.c.name == name,
tables.Flavors.c.project == project)).values(**fields) tables.Flavors.c.project == project)).values(**fields)
res = self._conn.execute(stmt) res = self.driver.connection.execute(stmt)
if res.rowcount == 0: if res.rowcount == 0:
raise errors.FlavorDoesNotExist(name) raise errors.FlavorDoesNotExist(name)
@ -127,12 +125,12 @@ class FlavorsController(base.FlavorsBase):
sa.and_(tables.Flavors.c.name == name, sa.and_(tables.Flavors.c.name == name,
tables.Flavors.c.project == project) tables.Flavors.c.project == project)
) )
self._conn.execute(stmt) self.driver.connection.execute(stmt)
@utils.raises_conn_error @utils.raises_conn_error
def drop_all(self): def drop_all(self):
stmt = sa.sql.expression.delete(tables.Flavors) stmt = sa.sql.expression.delete(tables.Flavors)
self._conn.execute(stmt) self.driver.connection.execute(stmt)
def _normalize(flavor, detailed=False): def _normalize(flavor, detailed=False):

View File

@ -30,11 +30,6 @@ from zaqar.storage.sqlalchemy import utils
class PoolsController(base.PoolsBase): class PoolsController(base.PoolsBase):
def __init__(self, *args, **kwargs):
super(PoolsController, self).__init__(*args, **kwargs)
self._conn = self.driver.connection
@utils.raises_conn_error @utils.raises_conn_error
def _list(self, marker=None, limit=10, detailed=False): def _list(self, marker=None, limit=10, detailed=False):
marker = marker or '' marker = marker or ''
@ -47,7 +42,7 @@ class PoolsController(base.PoolsBase):
) )
if limit > 0: if limit > 0:
stmt = stmt.limit(limit) stmt = stmt.limit(limit)
cursor = self._conn.execute(stmt) cursor = self.driver.connection.execute(stmt)
marker_name = {} marker_name = {}
@ -64,7 +59,7 @@ class PoolsController(base.PoolsBase):
stmt = sa.sql.select([tables.Pools]).where( stmt = sa.sql.select([tables.Pools]).where(
tables.Pools.c.group == group tables.Pools.c.group == group
) )
cursor = self._conn.execute(stmt) cursor = self.driver.connection.execute(stmt)
normalizer = functools.partial(_normalize, detailed=detailed) normalizer = functools.partial(_normalize, detailed=detailed)
return (normalizer(v) for v in cursor) return (normalizer(v) for v in cursor)
@ -75,7 +70,7 @@ class PoolsController(base.PoolsBase):
tables.Pools.c.name == name tables.Pools.c.name == name
) )
pool = self._conn.execute(stmt).fetchone() pool = self.driver.connection.execute(stmt).fetchone()
if pool is None: if pool is None:
raise errors.PoolDoesNotExist(name) raise errors.PoolDoesNotExist(name)
@ -84,7 +79,7 @@ class PoolsController(base.PoolsBase):
def _ensure_group_exists(self, name): def _ensure_group_exists(self, name):
try: try:
stmt = sa.sql.expression.insert(tables.PoolGroup).values(name=name) stmt = sa.sql.expression.insert(tables.PoolGroup).values(name=name)
self._conn.execute(stmt) self.driver.connection.execute(stmt)
return True return True
except sa.exc.IntegrityError: except sa.exc.IntegrityError:
return False return False
@ -101,7 +96,7 @@ class PoolsController(base.PoolsBase):
stmt = sa.sql.expression.insert(tables.Pools).values( stmt = sa.sql.expression.insert(tables.Pools).values(
name=name, weight=weight, uri=uri, group=group, options=opts name=name, weight=weight, uri=uri, group=group, options=opts
) )
self._conn.execute(stmt) self.driver.connection.execute(stmt)
except sa.exc.IntegrityError: except sa.exc.IntegrityError:
# TODO(cpp-cabrera): merge update/create into a single # TODO(cpp-cabrera): merge update/create into a single
@ -114,7 +109,7 @@ class PoolsController(base.PoolsBase):
stmt = sa.sql.select([tables.Pools.c.name]).where( stmt = sa.sql.select([tables.Pools.c.name]).where(
tables.Pools.c.name == name tables.Pools.c.name == name
).limit(1) ).limit(1)
return self._conn.execute(stmt).fetchone() is not None return self.driver.connection.execute(stmt).fetchone() is not None
@utils.raises_conn_error @utils.raises_conn_error
def _update(self, name, **kwargs): def _update(self, name, **kwargs):
@ -134,7 +129,7 @@ class PoolsController(base.PoolsBase):
stmt = sa.sql.update(tables.Pools).where( stmt = sa.sql.update(tables.Pools).where(
tables.Pools.c.name == name).values(**fields) tables.Pools.c.name == name).values(**fields)
res = self._conn.execute(stmt) res = self.driver.connection.execute(stmt)
if res.rowcount == 0: if res.rowcount == 0:
raise errors.PoolDoesNotExist(name) raise errors.PoolDoesNotExist(name)
@ -143,14 +138,14 @@ class PoolsController(base.PoolsBase):
stmt = sa.sql.expression.delete(tables.Pools).where( stmt = sa.sql.expression.delete(tables.Pools).where(
tables.Pools.c.name == name tables.Pools.c.name == name
) )
self._conn.execute(stmt) self.driver.connection.execute(stmt)
@utils.raises_conn_error @utils.raises_conn_error
def _drop_all(self): def _drop_all(self):
stmt = sa.sql.expression.delete(tables.Pools) stmt = sa.sql.expression.delete(tables.Pools)
self._conn.execute(stmt) self.driver.connection.execute(stmt)
stmt = sa.sql.expression.delete(tables.PoolGroup) stmt = sa.sql.expression.delete(tables.PoolGroup)
self._conn.execute(stmt) self.driver.connection.execute(stmt)
def _normalize(pool, detailed=False): def _normalize(pool, detailed=False):