fixed Storage copy

This commit is contained in:
mdipierro
2012-09-30 13:20:05 -05:00
parent 396f4449d8
commit 417c94470f
3 changed files with 38 additions and 40 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.0.9 (2012-09-30 08:37:19) dev Version 2.0.9 (2012-09-30 13:19:56) dev
+35 -38
View File
@@ -488,7 +488,7 @@ if 'google' in DRIVERS:
class ConnectionPool(object): class ConnectionPool(object):
pools = {} POOLS = {}
check_active_connection = True check_active_connection = True
@staticmethod @staticmethod
@@ -497,36 +497,31 @@ class ConnectionPool(object):
# ## this allows gluon to commit/rollback all dbs in this thread # ## this allows gluon to commit/rollback all dbs in this thread
@staticmethod def close(self,action='commit',really=True):
def recycle_connection(adapter,action):
if action: if action:
if callable(action): if callable(action):
action(adapter) action(self)
else: else:
getattr(adapter, action)() getattr(self, action)()
# ## if you want pools, recycle this connection # ## if you want pools, recycle this connection
really = True if self.pool_size:
if adapter.pool_size:
GLOBAL_LOCKER.acquire() GLOBAL_LOCKER.acquire()
pool = ConnectionPool.pools[adapter.uri] pool = ConnectionPool.POOLS[self.uri]
if len(pool) < adapter.pool_size: if len(pool) < self.pool_size:
pool.append(adapter.connection) pool.append(self.connection)
really = False really = False
GLOBAL_LOCKER.release() GLOBAL_LOCKER.release()
if really: if really:
getattr(adapter, 'close')() self.close_connection()
self.connection = None
@staticmethod @staticmethod
def close_all_instances(action): def close_all_instances(action):
""" to close cleanly databases in a multithreaded environment """ """ to close cleanly databases in a multithreaded environment """
dbs = getattr(THREAD_LOCAL,'db_instances',{}).items() dbs = getattr(THREAD_LOCAL,'db_instances',{}).items()
for singleton_code, db in dbs: for singleton_code, db in dbs:
try: if hasattr(db,'_adapter'):
adapter = db._adapter db._adapter.close(action)
except AttributeError:
pass
else:
ConnectionPool.recycle_connection(adapter,action)
del THREAD_LOCAL.db_instances[singleton_code] del THREAD_LOCAL.db_instances[singleton_code]
if callable(action): if callable(action):
action(None) action(None)
@@ -544,13 +539,7 @@ class ConnectionPool(object):
""" this it is suppoed to be overloaded by adtapters""" """ this it is suppoed to be overloaded by adtapters"""
pass pass
def reconnect(self): def pool_connection(self, f=None, cursor=True):
""" allows a thread to re-connect to server or re-pool """
ConnectionPool.recycle_connection(self,False) ### WHY?
self.pool_connection(self._connection_function)
self.after_connection()
def pool_connection(self, f, cursor=True):
""" """
this function defines: self.connection and self.cursor this function defines: self.connection and self.cursor
(iff cursor is True) (iff cursor is True)
@@ -558,19 +547,25 @@ class ConnectionPool(object):
if the connection is not active (closed by db server) it will loop 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 not self.pool_size or no active connections in pool makes a new one
""" """
pools = ConnectionPool.pools if getattr(self,'connection',None) != None:
self._connection_function = f return
if not f is None:
self._connection_function = f
else:
f = self._connection_function
if not self.pool_size: if not self.pool_size:
self.connection = f() self.connection = f()
self.cursor = cursor and self.connection.cursor() self.cursor = cursor and self.connection.cursor()
else: else:
uri = self.uri uri = self.uri
POOLS = ConnectionPool.POOLS
while True: while True:
GLOBAL_LOCKER.acquire() GLOBAL_LOCKER.acquire()
if not uri in pools: if not uri in POOLS:
pools[uri] = [] POOLS[uri] = []
if pools[uri]: if POOLS[uri]:
self.connection = pools[uri].pop() self.connection = POOLS[uri].pop()
GLOBAL_LOCKER.release() GLOBAL_LOCKER.release()
self.cursor = cursor and self.connection.cursor() self.cursor = cursor and self.connection.cursor()
try: try:
@@ -584,6 +579,8 @@ class ConnectionPool(object):
self.connection = f() self.connection = f()
self.cursor = cursor and self.connection.cursor() self.cursor = cursor and self.connection.cursor()
break break
self.after_connection()
################################################################################### ###################################################################################
# this is a generic adapter that does nothing; all others are derived from this one # this is a generic adapter that does nothing; all others are derived from this one
@@ -1638,7 +1635,7 @@ class BaseAdapter(ConnectionPool):
def rollback(self): def rollback(self):
return self.connection.rollback() return self.connection.rollback()
def close(self): def close_connection(self):
return self.connection.close() return self.connection.close()
def distributed_transaction_begin(self, key): def distributed_transaction_begin(self, key):
@@ -3968,7 +3965,7 @@ class DatabaseStoredFile:
def write(self,data): def write(self,data):
self.data += data self.data += data
def close(self): def close_connection(self):
self.db.executesql("DELETE FROM web2py_filesystem WHERE path='%s'" \ self.db.executesql("DELETE FROM web2py_filesystem WHERE path='%s'" \
% self.filename) % self.filename)
query = "INSERT INTO web2py_filesystem(path,content) VALUES ('%s','%s')"\ query = "INSERT INTO web2py_filesystem(path,content) VALUES ('%s','%s')"\
@@ -4154,7 +4151,7 @@ class NoSQLAdapter(BaseAdapter):
""" """
pass pass
def close(self): def close_connection(self):
""" """
remember: no transactions on many NoSQL remember: no transactions on many NoSQL
""" """
@@ -5526,7 +5523,7 @@ class IMAPAdapter(NoSQLAdapter):
closing closing
""" """
pools = ConnectionPool.pools POOLS = ConnectionPool.POOLS
if not self.pool_size: if not self.pool_size:
self.connection = f() self.connection = f()
self.cursor = cursor and self.connection.cursor() self.cursor = cursor and self.connection.cursor()
@@ -5534,10 +5531,10 @@ class IMAPAdapter(NoSQLAdapter):
uri = self.uri uri = self.uri
while True: while True:
GLOBAL_LOCKER.acquire() GLOBAL_LOCKER.acquire()
if not uri in pools: if not uri in POOLS:
pools[uri] = [] POOLS[uri] = []
if pools[uri]: if POOLS[uri]:
self.connection = pools[uri].pop() self.connection = POOLS[uri].pop()
GLOBAL_LOCKER.release() GLOBAL_LOCKER.release()
self.cursor = cursor and self.connection.cursor() self.cursor = cursor and self.connection.cursor()
if self.cursor and self.check_active_connection: if self.cursor and self.check_active_connection:
+2 -1
View File
@@ -46,7 +46,8 @@ class Storage(dict):
__repr__ = lambda self: '<Storage %s>' % dict.__repr__(self) __repr__ = lambda self: '<Storage %s>' % dict.__repr__(self)
# http://stackoverflow.com/questions/5247250/why-does-pickle-getstate-accept-as-a-return-value-the-very-instance-it-requi # http://stackoverflow.com/questions/5247250/why-does-pickle-getstate-accept-as-a-return-value-the-very-instance-it-requi
__getstate__ = lambda self: None __getstate__ = lambda self: None
# __reduce_ex__ = None __copy__ = lambda self: Storage(self)
def getlist(self,key): def getlist(self,key):
""" """