public synchronized long timeToAllowUpdate(long nowMs) {
        // Calculate the backoff for attempts which acts when metadata responses fail
        long backoffForAttempts = Math.max(this.lastRefreshMs +
                this.refreshBackoff.backoff(this.attempts > 0 ? this.attempts - 1 : 0) - nowMs, 0);

        // Periodic updates based on expiration resets the equivalent response count so exponential backoff is not used
        if (Math.max(this.lastSuccessfulRefreshMs + this.metadataExpireMs - nowMs, 0) == 0) {
            this.equivalentResponseCount = 0;
        }

        // Calculate the backoff for equivalent responses which acts when metadata responses are not making progress
        long backoffForEquivalentResponseCount = Math.max(this.lastRefreshMs +
                (this.equivalentResponseCount > 0 ? this.refreshBackoff.backoff(this.equivalentResponseCount - 1) : 0) - nowMs, 0);

        return Math.max(backoffForAttempts, backoffForEquivalentResponseCount);
    }
Return the next time when the current cluster info can be updated (i.e., backoff time has elapsed).
There are two calculations for backing off based on how many attempts to retrieve metadata have been made
since the last successful response, and how many equivalent metadata responses have been received.
The second of these allows backing off when there are errors to do with stale metadata, even though the
metadata responses are clean.
<p>
This can be used to check whether it's worth requesting an update in the knowledge that it will
not be delayed if this method returns 0.

@param nowMs current time in ms
@return remaining time in ms till the cluster info can be updated again
clients/src/main/java/org/apache/kafka/clients/Metadata.java