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
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
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
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()})
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()))
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()))
def _request_str(self, conn, url): '''Return string representation of connection.''' return "%s %s/%s" % (self._method, _conn_str(conn), url)