def fill_pool(self):
        """
        Add connections as necessary to meet the target pool size. If there
        are no nodes to connect to (because we maxed out connections-per-node
        on all active connections and any unconnected nodes have pending
        reconnect timers), call the on_insufficient_nodes callback.
        """

        time_since_last_called = self.fill_pool_throttle
        if self.fill_pool_last_called is not None:
            time_since_last_called = time() - self.fill_pool_last_called
        need = self.target_pool_size - self.num_connectors()
        if need <= 0 or (self.throttle_timer is not None and self.throttle_timer.active()):
            return
        elif time_since_last_called < self.fill_pool_throttle:
            self.log("Filling pool too quickly, calling again in %.1f seconds" % self.fill_pool_throttle)
            self._set_fill_pool_timer()
            return
        else:
            try:
                for num, node in izip(xrange(need), self.choose_nodes_to_connect()):
                    self.make_conn(node)
                self.fill_pool_last_called = time()

            except NoNodesAvailable, e:
                waittime = e.args[0]
                pending_requests = len(self.request_queue.pending)
                if self.on_insufficient_nodes:
                    self.on_insufficient_nodes(self.num_active_conns(),
                                               self.target_pool_size,
                                               pending_requests,
                                               waittime if waittime != float('Inf') else None)
                self.schedule_future_fill_pool(e.args[0])
                if self.num_connectors() == 0 and pending_requests > 0:
                    if self.on_insufficient_conns:
                        self.on_insufficient_conns(self.num_connectors(),
                                                   pending_requests)