Exemple #1
0
    def borrow_connection(self, timeout):
        if self.is_shutdown:
            raise ConnectionException(
                "Pool for %s is shutdown" % (self.host, ), self.host)

        conns = self._connections
        if not conns:
            # handled specially just for simpler code
            log.debug("Detected empty pool, opening core conns to %s",
                      self.host)
            core_conns = self._session.cluster.get_core_connections_per_host(
                self.host_distance)
            with self._lock:
                # we check the length of self._connections again
                # along with self._scheduled_for_creation while holding the lock
                # in case multiple threads hit this condition at the same time
                to_create = core_conns - (len(self._connections) +
                                          self._scheduled_for_creation)
                for i in range(to_create):
                    self._scheduled_for_creation += 1
                    self._session.submit(self._create_new_connection)

            # in_flight is incremented by wait_for_conn
            conn = self._wait_for_conn(timeout)
            return conn
        else:
            # note: it would be nice to push changes to these config settings
            # to pools instead of doing a new lookup on every
            # borrow_connection() call
            max_reqs = self._session.cluster.get_max_requests_per_connection(
                self.host_distance)
            max_conns = self._session.cluster.get_max_connections_per_host(
                self.host_distance)

            least_busy = min(conns, key=lambda c: c.in_flight)
            # to avoid another thread closing this connection while
            # trashing it (through the return_connection process), hold
            # the connection lock from this point until we've incremented
            # its in_flight count
            need_to_wait = False
            with least_busy.lock:

                if least_busy.in_flight >= MAX_STREAM_PER_CONNECTION:
                    # once we release the lock, wait for another connection
                    need_to_wait = True
                else:
                    least_busy.in_flight += 1

            if need_to_wait:
                # wait_for_conn will increment in_flight on the conn
                least_busy = self._wait_for_conn(timeout)

            # if we have too many requests on this connection but we still
            # have space to open a new connection against this host, go ahead
            # and schedule the creation of a new connection
            if least_busy.in_flight >= max_reqs and len(
                    self._connections) < max_conns:
                self._maybe_spawn_new_connection()

            return least_busy
Exemple #2
0
    def borrow_connection(self, timeout, routing_key=None):
        if self.is_shutdown:
            raise ConnectionException(
                "Pool for %s is shutdown" % (self.host, ), self.host)

        if not self._connections:
            raise NoConnectionsAvailable()

        shard_id = None
        if self.host.sharding_info and routing_key:
            t = self._session.cluster.metadata.token_map.token_class.from_key(
                routing_key)
            shard_id = self.host.sharding_info.shard_id_from_token(t)

        conn = self._connections.get(shard_id)

        # missing shard aware connection to shard_id, let's schedule an
        # optimistic try to connect to it
        if shard_id is not None:
            if conn:
                log.debug(
                    "Using connection to shard_id=%i on host %s for routing_key=%s",
                    shard_id, self.host, routing_key)
            elif shard_id not in self._connecting:
                # rate controlled optimistic attempt to connect to a missing shard
                self._connecting.add(shard_id)
                self._session.submit(self._open_connection_to_missing_shard,
                                     shard_id)
                log.debug(
                    "Trying to connect to missing shard_id=%i on host %s (%s/%i)",
                    shard_id, self.host, len(self._connections.keys()),
                    self.host.sharding_info.shards_count)

        # we couldn't find a shard aware connection, let's pick a random one
        # from our pool
        if not conn:
            conn = self._connections.get(
                random.choice(list(self._connections.keys())))

        start = time.time()
        remaining = timeout
        while True:
            with conn.lock:
                if conn.in_flight <= conn.max_request_id:
                    conn.in_flight += 1
                    return conn, conn.get_request_id()
            if timeout is not None:
                remaining = timeout - time.time() + start
                if remaining < 0:
                    break
            with self._stream_available_condition:
                self._stream_available_condition.wait(remaining)

        raise NoConnectionsAvailable("All request IDs are currently in use")
Exemple #3
0
    def borrow_connection(self, timeout):
        if self.is_shutdown:
            raise ConnectionException(
                "Pool for %s is shutdown" % (self.host, ), self.host)

        conn = self._connection
        if not conn:
            raise NoConnectionsAvailable()

        with conn.lock:
            if conn.in_flight < conn.max_request_id:
                conn.in_flight += 1
                return conn, conn.get_request_id()

        raise NoConnectionsAvailable("All request IDs are currently in use")
 def connect(self, address):
     # this is copied directly from asyncore.py, except that
     # a timeout is set before connecting
     self.connected = False
     self.connecting = True
     self.socket.settimeout(1.0)
     err = self.socket.connect_ex(address)
     if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \
     or err == EINVAL and os.name in ('nt', 'ce'):
         raise ConnectionException("Timed out connecting to %s" % (address[0]))
     if err in (0, EISCONN):
         self.addr = address
         self.setblocking(0)
         self.handle_connect_event()
     else:
         raise socket.error(err, errorcode[err])
Exemple #5
0
    def _wait_for_conn(self, timeout):
        start = time.time()
        remaining = timeout

        while remaining > 0:
            # wait on our condition for the possibility that a connection
            # is useable
            self._await_available_conn(remaining)

            # self.shutdown() may trigger the above Condition
            if self.is_shutdown:
                raise ConnectionException("Pool is shutdown")

            conns = self._connections
            if conns:
                least_busy = min(conns, key=lambda c: c.in_flight)
                with least_busy.lock:
                    if least_busy.in_flight < least_busy.max_request_id:
                        least_busy.in_flight += 1
                        return least_busy, least_busy.get_request_id()

            remaining = timeout - (time.time() - start)

        raise NoConnectionsAvailable()
Exemple #6
0
    def borrow_connection(self, timeout):
        if self.is_shutdown:
            raise ConnectionException(
                "Pool for %s is shutdown" % (self.host, ), self.host)

        conn = self._connection
        if not conn:
            raise NoConnectionsAvailable()

        start = time.time()
        remaining = timeout
        while True:
            with conn.lock:
                if conn.in_flight <= conn.max_request_id:
                    conn.in_flight += 1
                    return conn, conn.get_request_id()
            if timeout is not None:
                remaining = timeout - time.time() + start
                if remaining < 0:
                    break
            with self._stream_available_condition:
                self._stream_available_condition.wait(remaining)

        raise NoConnectionsAvailable("All request IDs are currently in use")
 def info_callback(self, connection, where, ret):
     if where & SSL.SSL_CB_HANDSHAKE_DONE:
         if self.check_hostname and self.endpoint.address != connection.get_peer_certificate().get_subject().commonName:
             transport = connection.get_app_data()
             transport.failVerification(Failure(ConnectionException("Hostname verification failed", self.endpoint)))