'Send a metadata request if needed.
Returns:
int: milliseconds until next refresh'

def _maybe_refresh_metadata(self):

    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
    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 (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)
        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 self._connecting:
        return self.config['request_timeout_ms']
    if self._can_connect(node_id):
        log.debug('Initializing    connection    to    node    %s    for    metadata    request', node_id)
        self._maybe_connect(node_id)
        return self.config['reconnect_backoff_ms']
    return float('inf')
