docs: def _maybe_refresh_metadata(self, wakeup=False):
          """Send a metadata request if needed.
  
          Returns:
              int: milliseconds until next refresh
          """
          ttl = self.cluster.ttl()
          wait_for_in_progress_ms = self.config['request_timeout_ms'] if self._metadata_refresh_in_progress else 0
          metadata_timeout = max(ttl, wait_for_in_progress_ms)
  
          if metadata_timeout > 0:
              return metadata_timeout
  
          # Beware that the behavior of this method and the computation of
          # timeouts for poll() are highly dependent on the behavior of
          # least_loaded_node()
          node_id = self.least_loaded_node()
          if node_id is None:
              log.debug("Give up sending metadata request since no node is available");
              return self.config['reconnect_backoff_ms']
  
          if self._can_send_request(node_id):
              topics = list(self._topics)
              if not topics and self.cluster.is_bootstrap(node_id):
                  topics = list(self.config['bootstrap_topics_filter'])
  
              if self.cluster.need_all_topic_metadata or not topics:
                  topics = [] if self.config['api_version'] < (0, 10) else None
              api_version = 0 if self.config['api_version'] < (0, 10) else 1
              request = MetadataRequest[api_version](topics)
              log.debug("Sending metadata request %s to node %s", request, node_id)
              future = self.send(node_id, request, wakeup=wakeup)
              future.add_callback(self.cluster.update_metadata)
              future.add_errback(self.cluster.failed_update)
  
              self._metadata_refresh_in_progress = True
              def refresh_done(val_or_error):
                  self._metadata_refresh_in_progress = False
              future.add_callback(refresh_done)
              future.add_errback(refresh_done)
              return self.config['request_timeout_ms']
  
          # If there's any connection establishment underway, wait until it completes. This prevents
          # the client from unnecessarily connecting to additional nodes while a previous connection
          # attempt has not been completed.
          if self._connecting:
              return self.config['reconnect_backoff_ms']
  
          if self.maybe_connect(node_id, wakeup=wakeup):
              log.debug("Initializing connection to node %s for metadata request", node_id)
              return self.config['reconnect_backoff_ms']
  
          # connected but can't send more, OR connecting
          # In either case we just need to wait for a network event
          # to let us know the selected connection might be usable again.
          return float('inf')