def _on_change(self): def lfunction(): self._data.select(transaction=self._transaction) self._row = self._data.fetchone() self._data.close() with_lock(self._data_object_lock, lfunction) self._callback(self)
def __init__(self, name, callback=None, transaction=None): """Inicializuj instanci. Argumenty: name -- určuje název specifikace datového objektu pro resolver. callback -- pokud není None, bude daná funkce volána při každé změně v datovém objektu. Jde o funkci jednoho argumentu, kterým je (aktualizovaná) instance 'DBConfig'. """ key = (name, transaction) try: data = DBConfig._data_object_cache[key] except KeyError: from pytis.extensions import data_object data = data_object(name) if data is not None: DBConfig._data_object_cache[key] = data self._data = data self._transaction = transaction def lfunction(): data.select(transaction=transaction) self._row = data.fetchone() data.close() with_lock(self._data_object_lock, lfunction) self._key = [self._row[c.id()] for c in data.key()] if callback: self._callback = callback self._data.add_callback_on_change(self._on_change)
def __del__(self): # Pro jistotu uzavíráme všechna spojení, přestože by to mělo být # zbytečné a zajištěno automaticky v pyPgSQL; třeba to pomůže # problému pozůstalých spojení. Navíc pro jistotu zamykáme, co # kdyby ... def lfunction(): for c in flatten(self._pool.values()): try: self._connection_closer(c) except: pass with_lock(self._lock, lfunction)
def put_back(self, connection_spec, connection): pool = self._pool spec_id = self._connection_spec_id(connection_spec) def lfunction(): try: connections = pool[spec_id] except KeyError: pool[spec_id] = connections = [] import config if ((config.max_pool_connections is None or len(connections) < config.max_pool_connections)): connections.append(connection) with_lock(self._lock, lfunction) if __debug__: log(DEBUG, 'Connection returned to pool:', connection)
def flush(self, close): def lfunction(): for connections in self._allocated_connections.values(): for c in connections.keys(): try: close(c) except: pass for connections in self._pool.values(): for c in connections: try: close(c) except: pass self._allocated_connections = {} self._pool = {} with_lock(self._lock, lfunction)
def _notif_listen_loop(self): while True: while self._pgnotif_connection is None: time.sleep(10) try: self._notif_init_connection() for notification in self._registered_notifications: self._notif_do_registration(notification) except Exception as e: self._pgnotif_connection = None connection_ = self._pgnotif_connection connection = connection_.connection() if __debug__: log(DEBUG, 'Listening for notifications:', connection) def lfunction(): cursor = connection.cursor() try: fileno = connection.fileno() except AttributeError: # older psycogp2 versions fileno = cursor.fileno() return cursor, fileno cursor, fileno = with_lock(self._pg_query_lock, lfunction) try: select.select([fileno], [], [], None) except Exception as e: if __debug__: log(DEBUG, 'Socket error', e.args) break if __debug__: log(DEBUG, 'Input received') def lfunction(): notifications = [] try: connection.poll() ready = True except AttributeError: # older psycopg2 versions try: ready = cursor.isready() except dbapi.OperationalError: self._pg_notif_connection = None return notifications if ready: notifies = connection.notifies if notifies: if __debug__: log(DEBUG, 'Data change registered') notifications = [] while notifies: notifications.append(notifies.pop()[1]) return notifications notifications = with_locks((self._notif_connection_lock, self._pg_query_lock,), lfunction) if __debug__: log(DEBUG, 'Notifications received:', notifications) self._notif_invoke_callbacks(notifications)
def _notif_do_registration(self, notification): if notification not in self._registered_notifications: self._registered_notifications.append(notification) connection = self._pgnotif_connection query = 'listen "%s"' % (notification,) # TODO: Allow reconnection with re-registrations def lfunction(): return self._postgresql_query(connection, query, True) _result, self._pgnotif_connection = \ with_lock(self._pg_query_lock, lfunction)
def _notif_do_registration(self, notification): if notification not in self._registered_notifications: self._registered_notifications.append(notification) connection = self._pgnotif_connection query = 'listen "%s"' % (notification, ) # TODO: Allow reconnection with re-registrations def lfunction(): return self._postgresql_query(connection, query, True) _result, self._pgnotif_connection = \ with_lock(self._pg_query_lock, lfunction)
def get(self, connection_spec): import config pool = self._pool spec_id = self._connection_spec_id(connection_spec) def lfunction(): try: connections = pool[spec_id] except KeyError: pool[spec_id] = connections = [] try: allocated_connections = self._allocated_connections[spec_id] except KeyError: allocated_connections = self._allocated_connections[spec_id] \ = weakref.WeakKeyDictionary() c = None broken_connections_present = False while connections: c_candidate = connections.pop() if c_candidate.connection_info('broken'): broken_connections_present = True else: c = c_candidate if __debug__: log(DEBUG, 'Available connections:', connections) break if c is None or broken_connections_present: gc.collect() if c is None: if ((config.connection_limit is not None and len(allocated_connections) >= config.connection_limit)): if __debug__: log(EVENT, "Connections summary:") for c in allocated_connections.keys(): log(EVENT, "Connection:", c.connection_info('last_access')) raise DBSystemException(_(u"Too many database connections")) else: c = self._connection_creator(connection_spec) if __debug__: log(DEBUG, 'New connection created:', c) allocated_connections[c] = True return c c = with_lock(self._lock, lfunction) if __debug__: log(DEBUG, 'Passing connection:', c) return c
def _notif_listen_loop(self): while True: while self._pgnotif_connection is None: time.sleep(10) try: self._notif_init_connection() for notification in self._registered_notifications: self._notif_do_registration(notification) except Exception as e: self._pgnotif_connection = None connection_ = self._pgnotif_connection connection = connection_.connection() if __debug__: log(DEBUG, 'Listening for notifications:', connection) def lfunction(): cursor = connection.cursor() try: fileno = connection.fileno() except AttributeError: # older psycogp2 versions fileno = cursor.fileno() return cursor, fileno cursor, fileno = with_lock(self._pg_query_lock, lfunction) try: select.select([fileno], [], [], None) except Exception as e: if __debug__: log(DEBUG, 'Socket error', e.args) break if __debug__: log(DEBUG, 'Input received') def lfunction(): notifications = [] try: connection.poll() ready = True except AttributeError: # older psycopg2 versions try: ready = cursor.isready() except dbapi.OperationalError: self._pg_notif_connection = None return notifications if ready: notifies = connection.notifies if notifies: if __debug__: log(DEBUG, 'Data change registered') notifications = [] while notifies: notifications.append(notifies.pop()[1]) return notifications notifications = with_locks(( self._notif_connection_lock, self._pg_query_lock, ), lfunction) if __debug__: log(DEBUG, 'Notifications received:', notifications) self._notif_invoke_callbacks(notifications)