Skip to content

Commit

Permalink
Merge pull request #107 from gi0baro/master
Browse files Browse the repository at this point in the history
Maybe this will fix the "connections argument" ^^
  • Loading branch information
mdipierro committed Mar 24, 2015
2 parents ac090e3 + 6941958 commit b08cb1f
Showing 1 changed file with 26 additions and 21 deletions.
47 changes: 26 additions & 21 deletions pydal/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,69 @@
from ._globals import GLOBAL_LOCKER, THREAD_LOCAL
from .helpers.classes import UseDatabaseStoredFile

class ConnectionPool(object):

class ConnectionPool(object):
POOLS = {}
check_active_connection = True

@staticmethod
def set_folder(folder):
THREAD_LOCAL.folder = folder

# ## this allows gluon to commit/rollback all dbs in this thread

def close(self, action='commit', really=False):
def close(self, action='commit', really=True):
#: if we have an action (commit, rollback), try to execute it
succeeded = True
if action:
try:
if callable(action):
action(self)
else:
getattr(self, action)()
except:
really = True

# If you want pools, recycle this connection
if self.pool_size and really == False:
#: connection had some problems, we want to drop it
succeeded = False
#: if we have pools, we should recycle the connection (but only when
# we succeded in `action`, if any and `len(pool)` is good)
if self.pool_size and succeeded:
GLOBAL_LOCKER.acquire()
pool = ConnectionPool.POOLS[self.uri]
if len(pool) < self.pool_size:
pool.append(self.connection)
else:
really = True
really = False
GLOBAL_LOCKER.release()
#: closing the connection when we `really` want to, in particular:
# - when we had an exception running `action`
# - when we don't have pools
# - when we have pools but they're full
if really:
try:
self.close_connection()
except:
pass
#: always unset `connection` attribute
self.connection = None

@staticmethod
def close_all_instances(action):
""" to close cleanly databases in a multithreaded environment """
dbs = getattr(THREAD_LOCAL,'db_instances',{}).items()
dbs = getattr(THREAD_LOCAL, 'db_instances', {}).items()
for db_uid, db_group in dbs:
for db in db_group:
if hasattr(db,'_adapter'):
if hasattr(db, '_adapter'):
db._adapter.close(action)
getattr(THREAD_LOCAL,'db_instances',{}).clear()
getattr(THREAD_LOCAL,'db_instances_zombie',{}).clear()
getattr(THREAD_LOCAL, 'db_instances', {}).clear()
getattr(THREAD_LOCAL, 'db_instances_zombie', {}).clear()
if callable(action):
action(None)
return

def find_or_make_work_folder(self):
#this actually does not make the folder. it has to be there
self.folder = getattr(THREAD_LOCAL,'folder','')
self.folder = getattr(THREAD_LOCAL, 'folder', '')

if (os.path.isabs(self.folder) and
isinstance(self, UseDatabaseStoredFile) and
self.folder.startswith(os.getcwd())):
if os.path.isabs(self.folder) and \
isinstance(self, UseDatabaseStoredFile) and \
self.folder.startswith(os.getcwd()):
self.folder = os.path.relpath(self.folder, os.getcwd())

# Creating the folder if it does not exist
Expand All @@ -87,7 +92,7 @@ def reconnect(self, f=None, cursor=True):
if the connection is not active (closed by db server) it will loop
if not `self.pool_size` or no active connections in pool makes a new one
"""
if getattr(self,'connection', None) is not None:
if getattr(self, 'connection', None) is not None:
return
if f is None:
f = self.connector
Expand All @@ -104,15 +109,15 @@ def reconnect(self, f=None, cursor=True):
POOLS = ConnectionPool.POOLS
while True:
GLOBAL_LOCKER.acquire()
if not uri in POOLS:
if uri not in POOLS:
POOLS[uri] = []
if POOLS[uri]:
self.connection = POOLS[uri].pop()
GLOBAL_LOCKER.release()
self.cursor = cursor and self.connection.cursor()
try:
if self.cursor and self.check_active_connection:
self.execute(self.test_query)
self.execute(self.test_query)
break
except:
pass
Expand Down

0 comments on commit b08cb1f

Please sign in to comment.