docs: 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)