def release_connection(self, http_conn, bad_state=False):
        '''Mark HTTPConnection instance as available for check-out.

        Args:
            http_conn: An HTTPConnection instance obtained from this
                instance.
            bad_state: True if http_conn is known to be in a bad state
                (e.g. connection fault.)
        '''
        if self._conn_params(http_conn) not in self._api_providers:
            lg.debug("Released connection '%s' is no longer an API provider "
                     "for the cluster" % _conn_str(http_conn))
            return

        # Retrieve "home" connection pool.
        conn_pool = http_conn.conn_pool
        if bad_state:
            # reconnect
            lg.info("API connection fault, reconnecting to %s"
                    % _conn_str(http_conn))
            http_conn = self._create_connection(*self._conn_params(http_conn))
            http_conn.conn_pool = conn_pool
            conn_pool.put(http_conn)

            if self._active_conn_pool == http_conn.conn_pool:
                # Get next connection from the connection pool and make it
                # active.
                lg.info("API connection fault changing active_conn_pool.")
                self._conn_pool.put(self._active_conn_pool)
                self._active_conn_pool = self._conn_pool.get()
                self._issue_conn_barrier = time.time() + self._failover_time
        else:
            conn_pool.put(http_conn)

        lg.debug("API client connection %s released" % _conn_str(http_conn))
    def acquire_connection(self):
        '''Check out an available HTTPConnection instance.

        Blocks until a connection is available.

        Returns: An available HTTPConnection instance or None if no
                 api_providers are configured.
        '''
        if not self._api_providers:
            return None

        # The sleep time is to give controllers time to become consistent after
        # there has been a change in the controller used as the api_provider.
        now = time.time()
        if now < getattr(self, '_issue_conn_barrier', now):
            lg.info("acquire_connection() waiting for timer to expire.")
            time.sleep(self._issue_conn_barrier - now)

        if self._active_conn_pool.empty():
            lg.debug("Waiting to acquire an API client connection")

        # get() call is blocking.
        conn = self._active_conn_pool.get()
        now = time.time()
        if getattr(conn, 'last_used', now) < now - self.CONN_IDLE_TIMEOUT:
            lg.info("Connection %s idle for %0.2f seconds; reconnecting."
                    % (_conn_str(conn), now - conn.last_used))
            conn = self._create_connection(*self._conn_params(conn))

            # Stash conn pool so conn knows where to go when it releases.
            conn.conn_pool = self._active_conn_pool

        conn.last_used = now
        lg.debug("API client connection %s acquired" % _conn_str(conn))
        return conn
示例#3
0
    def acquire_connection(self, rid=-1):
        '''Check out an available HTTPConnection instance.

        Blocks until a connection is available.

        :param rid: request id passed in from request eventlet.
        :returns: An available HTTPConnection instance or None if no
                 api_providers are configured.
        '''
        if not self._api_providers:
            LOG.warn(_("[%d] no API providers currently available."), rid)
            return None

        # The sleep time is to give controllers time to become consistent after
        # there has been a change in the controller used as the api_provider.
        now = time.time()
        if now < getattr(self, '_issue_conn_barrier', now):
            LOG.warn(_("[%d] Waiting for failover timer to expire."), rid)
            time.sleep(self._issue_conn_barrier - now)

        # Print out a warning if all connections are in use.
        if self._conn_pool[self._active_conn_pool_idx].empty():
            LOG.debug(_("[%d] Waiting to acquire client connection."), rid)

        # Try to acquire a connection (block in get() until connection
        # available or timeout occurs).
        active_conn_pool_idx = self._active_conn_pool_idx
        conn = self._conn_pool[active_conn_pool_idx].get()

        if active_conn_pool_idx != self._active_conn_pool_idx:
            # active_conn_pool became inactive while we were waiting.
            # Put connection back on old pool and try again.
            LOG.warn(_("[%(rid)d] Active pool expired while waiting for "
                       "connection: %(conn)s"),
                     {'rid': rid, 'conn': _conn_str(conn)})
            self._conn_pool[active_conn_pool_idx].put(conn)
            return self.acquire_connection(rid=rid)

        # Check if the connection has been idle too long.
        now = time.time()
        if getattr(conn, 'last_used', now) < now - self.CONN_IDLE_TIMEOUT:
            LOG.info(_("[%(rid)d] Connection %(conn)s idle for %(sec)0.2f "
                       "seconds; reconnecting."),
                     {'rid': rid, 'conn': _conn_str(conn),
                      'sec': now - conn.last_used})
            conn = self._create_connection(*self._conn_params(conn))

            # Stash conn pool so conn knows where to go when it releases.
            conn.idx = self._active_conn_pool_idx

        conn.last_used = now
        qsize = self._conn_pool[self._active_conn_pool_idx].qsize()
        LOG.debug(_("[%(rid)d] Acquired connection %(conn)s. %(qsize)d "
                    "connection(s) available."),
                  {'rid': rid, 'conn': _conn_str(conn), 'qsize': qsize})
        return conn
示例#4
0
    def acquire_connection(self, rid=-1):
        '''Check out an available HTTPConnection instance.

        Blocks until a connection is available.

        :param rid: request id passed in from request eventlet.
        :returns: An available HTTPConnection instance or None if no
                 api_providers are configured.
        '''
        if not self._api_providers:
            lg.warn("[%d] no API providers currently available." % rid)
            return None

        # The sleep time is to give controllers time to become consistent after
        # there has been a change in the controller used as the api_provider.
        now = time.time()
        if now < getattr(self, '_issue_conn_barrier', now):
            lg.warn("[%d] Waiting for failover timer to expire." % rid)
            time.sleep(self._issue_conn_barrier - now)

        # Print out a warning if all connections are in use.
        if self._conn_pool[self._active_conn_pool_idx].empty():
            lg.debug("[%d] Waiting to acquire client connection." % rid)

        # Try to acquire a connection (block in get() until connection
        # available or timeout occurs).
        active_conn_pool_idx = self._active_conn_pool_idx
        conn = self._conn_pool[active_conn_pool_idx].get()

        if active_conn_pool_idx != self._active_conn_pool_idx:
            # active_conn_pool became inactive while we were waiting.
            # Put connection back on old pool and try again.
            lg.warn(
                "[%d] Active pool expired while waiting for connection: %s" %
                (rid, _conn_str(conn)))
            self._conn_pool[active_conn_pool_idx].put(conn)
            return self.acquire_connection(rid=rid)

        # Check if the connection has been idle too long.
        now = time.time()
        if getattr(conn, 'last_used', now) < now - self.CONN_IDLE_TIMEOUT:
            lg.info(
                "[%d] Connection %s idle for %0.2f seconds; reconnecting." %
                (rid, _conn_str(conn), now - conn.last_used))
            conn = self._create_connection(*self._conn_params(conn))

            # Stash conn pool so conn knows where to go when it releases.
            conn.idx = self._active_conn_pool_idx

        conn.last_used = now
        qsize = self._conn_pool[self._active_conn_pool_idx].qsize()
        lg.debug("[%d] Acquired connection %s. %d connection(s) available." %
                 (rid, _conn_str(conn), qsize))
        return conn
示例#5
0
    def release_connection(self, http_conn, bad_state=False, rid=-1):
        '''Mark HTTPConnection instance as available for check-out.

        :param http_conn: An HTTPConnection instance obtained from this
            instance.
        :param bad_state: True if http_conn is known to be in a bad state
                (e.g. connection fault.)
        :param rid: request id passed in from request eventlet.
        '''
        if self._conn_params(http_conn) not in self._api_providers:
            LOG.warn(_("[%(rid)d] Released connection '%(conn)s' is not an "
                       "API provider for the cluster"),
                     {'rid': rid, 'conn': _conn_str(http_conn)})
            return

        # Retrieve "home" connection pool.
        conn_pool_idx = http_conn.idx
        conn_pool = self._conn_pool[conn_pool_idx]
        if bad_state:
            # Reconnect to provider.
            LOG.warn(_("[%(rid)d] Connection returned in bad state, "
                       "reconnecting to %(conn)s"),
                     {'rid': rid, 'conn': _conn_str(http_conn)})
            http_conn = self._create_connection(*self._conn_params(http_conn))
            http_conn.idx = conn_pool_idx

            if self._active_conn_pool_idx == http_conn.idx:
                # This pool is no longer in a good state. Switch to next pool.
                self._active_conn_pool_idx += 1
                self._active_conn_pool_idx %= len(self._conn_pool)
                LOG.warn(_("[%(rid)d] Switched active_conn_pool from "
                           "%(idx)d to %(pool_idx)d."),
                         {'rid': rid, 'idx': http_conn.idx,
                          'pool_idx': self._active_conn_pool_idx})

                # No connections to the new provider allowed until after this
                # timer has expired (allow time for synchronization).
                self._issue_conn_barrier = time.time() + self._failover_time

        conn_pool.put(http_conn)
        LOG.debug(_("[%(rid)d] Released connection %(conn)s. "
                    "%(qsize)d connection(s) available."),
                  {'rid': rid, 'conn': _conn_str(http_conn),
                   'qsize': conn_pool.qsize()})
示例#6
0
    def release_connection(self, http_conn, bad_state=False, rid=-1):
        '''Mark HTTPConnection instance as available for check-out.

        :param http_conn: An HTTPConnection instance obtained from this
            instance.
        :param bad_state: True if http_conn is known to be in a bad state
                (e.g. connection fault.)
        :param rid: request id passed in from request eventlet.
        '''
        if self._conn_params(http_conn) not in self._api_providers:
            lg.warn("[%d] Released connection '%s' is not an API provider "
                    "for the cluster" % (rid, _conn_str(http_conn)))
            return

        # Retrieve "home" connection pool.
        conn_pool_idx = http_conn.idx
        conn_pool = self._conn_pool[conn_pool_idx]
        if bad_state:
            # Reconnect to provider.
            lg.warn(
                "[%d] Connection returned in bad state, reconnecting to %s" %
                (rid, _conn_str(http_conn)))
            http_conn = self._create_connection(*self._conn_params(http_conn))
            http_conn.idx = conn_pool_idx

            if self._active_conn_pool_idx == http_conn.idx:
                # This pool is no longer in a good state. Switch to next pool.
                self._active_conn_pool_idx += 1
                self._active_conn_pool_idx %= len(self._conn_pool)
                lg.warn("[%d] Switched active_conn_pool from %d to %d." %
                        (rid, http_conn.idx, self._active_conn_pool_idx))

                # No connections to the new provider allowed until after this
                # timer has expired (allow time for synchronization).
                self._issue_conn_barrier = time.time() + self._failover_time

        conn_pool.put(http_conn)
        lg.debug("[%d] Released connection %s. %d connection(s) available." %
                 (rid, _conn_str(http_conn), conn_pool.qsize()))
示例#7
0
    def release_connection(self, http_conn, bad_state=False, rid=-1):
        '''Mark HTTPConnection instance as available for check-out.

        :param http_conn: An HTTPConnection instance obtained from this
            instance.
        :param bad_state: True if http_conn is known to be in a bad state
                (e.g. connection fault.)
        :param rid: request id passed in from request eventlet.
        '''
        if self._conn_params(http_conn) not in self._api_providers:
            lg.warn("[%d] Released connection '%s' is not an API provider "
                    "for the cluster" % (rid, _conn_str(http_conn)))
            return

        # Retrieve "home" connection pool.
        conn_pool_idx = http_conn.idx
        conn_pool = self._conn_pool[conn_pool_idx]
        if bad_state:
            # Reconnect to provider.
            lg.warn("[%d] Connection returned in bad state, reconnecting to %s"
                    % (rid, _conn_str(http_conn)))
            http_conn = self._create_connection(*self._conn_params(http_conn))
            http_conn.idx = conn_pool_idx

            if self._active_conn_pool_idx == http_conn.idx:
                # This pool is no longer in a good state. Switch to next pool.
                self._active_conn_pool_idx += 1
                self._active_conn_pool_idx %= len(self._conn_pool)
                lg.warn("[%d] Switched active_conn_pool from %d to %d."
                        % (rid, http_conn.idx, self._active_conn_pool_idx))

                # No connections to the new provider allowed until after this
                # timer has expired (allow time for synchronization).
                self._issue_conn_barrier = time.time() + self._failover_time

        conn_pool.put(http_conn)
        lg.debug("[%d] Released connection %s. %d connection(s) available."
                 % (rid, _conn_str(http_conn), conn_pool.qsize()))
示例#8
0
 def _request_str(self, conn, url):
     '''Return string representation of connection.'''
     return "%s %s/%s" % (self._method, _conn_str(conn), url)
示例#9
0
 def _request_str(self, conn, url):
     '''Return string representation of connection.'''
     return "%s %s/%s" % (self._method, _conn_str(conn), url)