diff options
author | Patrick Uiterwijk <puiterwijk@redhat.com> | 2015-04-14 13:00:25 +0200 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2015-04-15 10:35:04 -0400 |
commit | 800b39df6e2c65fa06a0d5da48002bb26b83b435 (patch) | |
tree | a1b1cbe5b437a09dd3796de2318772a89c75cab3 /ipsilon/util/data.py | |
parent | f73332fb7d55bd5753a8bafc2493172203fcf377 (diff) | |
download | ipsilon-800b39df6e2c65fa06a0d5da48002bb26b83b435.tar.gz ipsilon-800b39df6e2c65fa06a0d5da48002bb26b83b435.tar.xz ipsilon-800b39df6e2c65fa06a0d5da48002bb26b83b435.zip |
Close database sesssions
This will close any opened database sessions at the end
of the request.
https://fedorahosted.org/ipsilon/ticket/110
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
Reviewed-by: Rob Crittenden <rcritten@redhat.com>
Diffstat (limited to 'ipsilon/util/data.py')
-rw-r--r-- | ipsilon/util/data.py | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/ipsilon/util/data.py b/ipsilon/util/data.py index b06f00c..a365e33 100644 --- a/ipsilon/util/data.py +++ b/ipsilon/util/data.py @@ -19,6 +19,7 @@ import cherrypy from ipsilon.util.log import Log from sqlalchemy import create_engine from sqlalchemy import MetaData, Table, Column, Text +from sqlalchemy.pool import QueuePool, SingletonThreadPool from sqlalchemy.sql import select import ConfigParser import os @@ -30,19 +31,48 @@ UNIQUE_DATA_COLUMNS = ['uuid', 'name', 'value'] class SqlStore(Log): + __instances = {} + + @classmethod + def get_connection(cls, name): + if name not in cls.__instances.keys(): + print 'SqlStore new: %s' % name + cls.__instances[name] = SqlStore(name) + return cls.__instances[name] def __init__(self, name): + self.debug('SqlStore init: %s' % name) + self.name = name engine_name = name if '://' not in engine_name: engine_name = 'sqlite:///' + engine_name - self._dbengine = create_engine(engine_name) + # This pool size is per configured database. The minimum needed, + # determined by binary search, is 23. We're using 25 so we have a bit + # more playroom, and then the overflow should make sure things don't + # break when we suddenly need more. + pool_args = {'poolclass': QueuePool, + 'pool_size': 25, + 'max_overflow': 50} + if engine_name.startswith('sqlite://'): + # It's not possible to share connections for SQLite between + # threads, so let's use the SingletonThreadPool for them + pool_args = {'poolclass': SingletonThreadPool} + # pylint: disable=star-args + self._dbengine = create_engine(engine_name, **pool_args) self.is_readonly = False def engine(self): return self._dbengine def connection(self): - return self._dbengine.connect() + self.debug('SqlStore connect: %s' % self.name) + conn = self._dbengine.connect() + + def cleanup_connection(): + self.debug('SqlStore cleanup: %s' % self.name) + conn.close() + cherrypy.request.hooks.attach('on_end_request', cleanup_connection) + return conn def SqlAutotable(f): @@ -244,7 +274,7 @@ class Store(Log): self._db = FileStore(filename) self._query = FileQuery else: - self._db = SqlStore(name) + self._db = SqlStore.get_connection(name) self._query = SqlQuery @property |