Repository: apache/kafka
File: clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerRebalanceListener.java (Java)

Code before:
 *           for(TopicPartition partition: partitions)
 *              consumer.seek(partition, readOffsetFromExternalStore(partition));
 *       }
 *   }
 * }
 * </pre>
 */
public interface ConsumerRebalanceListener {

    /**
     * A callback method the user can implement to provide handling of offset commits to a customized store.
     * This method will be called during a rebalance operation when the consumer has to give up some partitions.
     * The consumer may need to give up some partitions (thus this callback executed) under the following scenarios:
     * <ul>
     *     <li>If the consumer assignment changes</li>
     *     <li>If the consumer is being closed ({@link KafkaConsumer#close(CloseOptions option)})</li>
     *     <li>If the consumer is unsubscribing ({@link KafkaConsumer#unsubscribe()})</li>
     * </ul>
     * It is recommended that offsets should be committed in this callback to either Kafka or a
     * custom offset store to prevent duplicate data.
     * <p>
     * This callback is always called before re-assigning the partitions.
     * If the consumer is using the {@link GroupProtocol#CLASSIC} rebalance protocol:
     * <ul>
     *     <li>
     *         In eager rebalancing, onPartitionsRevoked will be called with the full set of assigned partitions as parameter (all partitions are revoked).
     *         It will be called even if there are no partitions to revoke.
     *     </li>
     *     <li>
     *         In cooperative rebalancing, onPartitionsRevoked will be called with the set of partitions to revoked,
     *         iff the set is non-empty.
     *     </li>
     * </ul>
     * If the consumer is using the {@link GroupProtocol#CONSUMER} rebalance protocol, this callback will be called
     * with the set of partitions to revoked iff the set is non-empty
     * (same behavior as the {@link GroupProtocol#CLASSIC} rebalance protocol with Cooperative mode).
     * <p>
     * For examples on usage of this API, see Usage Examples section of {@link KafkaConsumer KafkaConsumer}.
     * <p>
     * It is common for the revocation callback to use the consumer instance in order to commit offsets. It is possible
     * for a {@link org.apache.kafka.common.errors.WakeupException} or {@link org.apache.kafka.common.errors.InterruptException}
     * to be raised from one of these nested invocations. In this case, the exception will be propagated to the current
     * invocation of {@link KafkaConsumer#poll(java.time.Duration)} in which this callback is being executed. This means it is not
     * necessary to catch these exceptions and re-attempt to wakeup or interrupt the consumer thread.
     *
     * @param partitions The list of partitions that were assigned to the consumer and now need to be revoked (may not
     *                   include all currently assigned partitions, i.e. there may still be some partitions left)
     * @throws org.apache.kafka.common.errors.WakeupException If raised from a nested call to {@link KafkaConsumer}
     * @throws org.apache.kafka.common.errors.InterruptException If raised from a nested call to {@link KafkaConsumer}
     */
    void onPartitionsRevoked(Collection<TopicPartition> partitions);

Review comment (suggestion):
```suggestion
     *         In eager rebalancing, onPartitionsRevoked will be called with the full set of assigned partitions as a parameter (all partitions are revoked).
```

Code after:
 *           for(TopicPartition partition: partitions)
 *              consumer.seek(partition, readOffsetFromExternalStore(partition));
 *       }
 *   }
 * }
 * </pre>
 */
public interface ConsumerRebalanceListener {

    /**
     * A callback method the user can implement to provide handling of offset commits to a customized store.
     * This method will be called during a rebalance operation when the consumer has to give up some partitions.
     * The consumer may need to give up some partitions (thus this callback executed) under the following scenarios:
     * <ul>
     *     <li>If the consumer assignment changes</li>
     *     <li>If the consumer is being closed ({@link KafkaConsumer#close(CloseOptions option)})</li>
     *     <li>If the consumer is unsubscribing ({@link KafkaConsumer#unsubscribe()})</li>
     * </ul>
     * It is recommended that offsets should be committed in this callback to either Kafka or a
     * custom offset store to prevent duplicate data.
     * <p>
     * This callback is always called before re-assigning the partitions.
     * If the consumer is using the {@link GroupProtocol#CLASSIC} rebalance protocol:
     * <ul>
     *     <li>
     *         In eager rebalancing, onPartitionsRevoked will be called with the full set of assigned partitions as a parameter (all partitions are revoked).
     *         It will be called even if there are no partitions to revoke.
     *     </li>
     *     <li>
     *         In cooperative rebalancing, onPartitionsRevoked will be called with the set of partitions to revoke,
     *         iff the set is non-empty.
     *     </li>
     * </ul>
     * If the consumer is using the {@link GroupProtocol#CONSUMER} rebalance protocol, this callback will be called
     * with the set of partitions to revoke iff the set is non-empty
     * (same behavior as the {@link GroupProtocol#CLASSIC} rebalance protocol with Cooperative mode).
     * <p>
     * For examples on usage of this API, see Usage Examples section of {@link KafkaConsumer KafkaConsumer}.
     * <p>
     * It is common for the revocation callback to use the consumer instance in order to commit offsets. It is possible
     * for a {@link org.apache.kafka.common.errors.WakeupException} or {@link org.apache.kafka.common.errors.InterruptException}
     * to be raised from one of these nested invocations. In this case, the exception will be propagated to the current
     * invocation of {@link KafkaConsumer#poll(java.time.Duration)} in which this callback is being executed. This means it is not
     * necessary to catch these exceptions and re-attempt to wakeup or interrupt the consumer thread.
     *
     * @param partitions The list of partitions that were assigned to the consumer and now need to be revoked. This will
     *                  include the full assignment under the Classic/Eager protocol, given that it revokes all partitions.
     *                   It will only include the subset to revoke under the Classic/Cooperative and Consumer protocols.
     * @throws org.apache.kafka.common.errors.WakeupException If raised from a nested call to {@link KafkaConsumer}
     * @throws org.apache.kafka.common.errors.InterruptException If raised from a nested call to {@link KafkaConsumer}
     */