def acquire_direct(self, address): """ Acquire a connection to a given address from the pool. The address supplied should always be an IP address, not a host name. This method is thread safe. """ if self.closed(): raise ServiceUnavailable("Connection pool closed") if not is_ip_address(address[0]): raise ValueError("Invalid IP address {!r}".format(address[0])) with self.lock: try: connections = self.connections[address] except KeyError: connections = self.connections[address] = deque() connection_acquisition_start_timestamp = clock() while True: # try to find a free connection in pool for connection in list(connections): if connection.closed() or connection.defunct( ) or connection.timedout(): connections.remove(connection) continue if not connection.in_use: connection.in_use = True return connection # all connections in pool are in-use can_create_new_connection = self._max_connection_pool_size == INFINITE or len( connections) < self._max_connection_pool_size if can_create_new_connection: try: connection = self.connector( address, self.connection_error_handler) except ServiceUnavailable: self.remove(address) raise else: connection.pool = self connection.in_use = True connections.append(connection) return connection # failed to obtain a connection from pool because the pool is full and no free connection in the pool span_timeout = self._connection_acquisition_timeout - ( clock() - connection_acquisition_start_timestamp) if span_timeout > 0: self.cond.wait(span_timeout) # if timed out, then we throw error. This time computation is needed, as with python 2.7, we cannot # tell if the condition is notified or timed out when we come to this line if self._connection_acquisition_timeout <= ( clock() - connection_acquisition_start_timestamp): raise ClientError( "Failed to obtain a connection from pool within {!r}s" .format(self._connection_acquisition_timeout)) else: raise ClientError( "Failed to obtain a connection from pool within {!r}s". format(self._connection_acquisition_timeout))
def acquire_direct(self, address): """ Acquire a connection to a given address from the pool. The address supplied should always be an IP address, not a host name. This method is thread safe. """ if self.closed(): raise ServiceUnavailable("Connection pool closed") if not is_ip_address(address[0]): raise ValueError("Invalid IP address {!r}".format(address[0])) with self.lock: try: connections = self.connections[address] except KeyError: connections = self.connections[address] = deque() for connection in list(connections): if connection.closed() or connection.defunct(): connections.remove(connection) continue if not connection.in_use: connection.in_use = True return connection try: connection = self.connector(address) except ServiceUnavailable: self.remove(address) raise else: connection.pool = self connection.in_use = True connections.append(connection) return connection