class ConsumerCoordinator extends AbstractCoordinator {

    public void ensurePartitionAssignment() {
        if (subscriptions.partitionsAutoAssigned()) {// SubscriptionType.AUTO_TOPICS 或 SubscriptionType.AUTO_PATTERN;

            // Due to a race condition between the initial metadata fetch and the initial rebalance, we need to ensure that
            // the metadata is fresh before joining initially, and then request the metadata update. If metadata update arrives
            // while the rebalance is still pending (for example, when the join group is still inflight), then we will lose
            // track of the fact that we need to rebalance again to reflect the change to the topic subscription. Without
            // ensuring that the metadata is fresh, any metadata update that changes the topic subscriptions and arrives with a
            // rebalance in progress will essentially be ignored. See KAFKA-3949 for the complete description of the problem.

            // 基于初始化获取metadata与初始化Rebalance的竞态条件，我们需要确保在进行初始化时，metadata是新的，然后
            // 请求metadata的更新。如果在rebalance还在等待时metadata的更新抵达了（比如，加入group的操作依旧inflight），
            // 我们将会丢失真实的踪迹？，所以我们需要再次rebalance来反应topic订阅情况的改变。在没有确保metadata是新鲜的之前，
            // 任何改变topic订阅以及在rebalance时到来的metadata更新将会被忽略。完整表述这个问题，可以看看 KAFKA-3949

            if (subscriptions.hasPatternSubscription()) {// SubscriptionType.AUTO_PATTERN
                client.ensureFreshMetadata();// 防止因为使用过期的Metadata进行Rebalance而导致多次连续的Rebalance
            }

            ensureActiveGroup();
        }
    }

    public  ConsumerCoordinator(ConsumerNetworkClient client,
        String groupId,
        int sessionTimeoutMs,
        int heartbeatIntervalMs,
        List<PartitionAssignor> assignors,
        Metadata metadata,
        SubscriptionState subscriptions,
        Metrics metrics,
        String metricGrpPrefix,
        Time time,
        long retryBackoffMs,
        OffsetCommitCallback defaultOffsetCommitCallback,
        boolean autoCommitEnabled,
        long autoCommitIntervalMs,
        ConsumerInterceptors<?, ?> interceptors,
        boolean excludeInternalTopics);

}