Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
 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)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
 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)
Ejemplo n.º 8
0
        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)
Ejemplo n.º 9
0
 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
Ejemplo n.º 10
0
        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)