[ 
https://issues.apache.org/jira/browse/KAFKA-21409?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18136032#comment-18136032
 ] 

Chia-Ping Tsai commented on KAFKA-21409:
----------------------------------------

 
{code:java}
    @Timeout(120)
    @ClusterTest(serverProperties = {
        @ClusterConfigProperty(key = 
CONSUMER_GROUP_ASSIGNMENT_INTERVAL_MS_CONFIG, value = "0")
    })
    public void 
testAsyncConsumerRe2JPatternSwitchToNonMatchingRegexReassignsPartitions() 
throws InterruptedException {
        var groupId = "regex-switch-group";
        Map<String, Object> config = Map.of(
            GROUP_PROTOCOL_CONFIG, 
GroupProtocol.CONSUMER.name().toLowerCase(Locale.ROOT),
            GROUP_ID_CONFIG, groupId
        );
        try (Consumer<byte[], byte[]> consumer1 = cluster.consumer(config);
             Consumer<byte[], byte[]> consumer2 = cluster.consumer(config)) {   
         // "topic" (2 partitions) is created by setup(). Both members 
subscribe to a regex
            // that matches it, so each one ends up with one partition.
            var matching = new SubscriptionPattern("topic.*");
            consumer1.subscribe(matching);
            consumer2.subscribe(matching);            Set<TopicPartition> all = 
Set.of(
                new TopicPartition(topic, 0),
                new TopicPartition(topic, 1)
            );
            TestUtils.waitForCondition(() -> {
                consumer1.poll(Duration.ofMillis(100));
                consumer2.poll(Duration.ofMillis(100));
                Set<TopicPartition> union = new 
HashSet<>(consumer1.assignment());
                union.addAll(consumer2.assignment());
                return consumer1.assignment().size() == 1
                    && consumer2.assignment().size() == 1
                    && union.equals(all);
            }, () -> "Expected one partition each, got " + 
consumer1.assignment() + " and " + consumer2.assignment());            // 
Member 2 switches, without leaving the group, to a regex that matches no topic.
            // The client gives its partition back; the coordinator should hand 
it to member 1.
            consumer2.subscribe(new 
SubscriptionPattern("nothing-matches-this.*"));            // First, member 2 
must give its partition back (the client treats an unresolved
            // or non-matching regex as subscribing to nothing).
            TestUtils.waitForCondition(() -> {
                consumer1.poll(Duration.ofMillis(100));
                consumer2.poll(Duration.ofMillis(100));
                return consumer2.assignment().isEmpty();
            }, 30_000L, () -> "Member 2 never released its partition: " + 
consumer2.assignment());            // Then member 1 should receive it. The 
regex refresh has a 10s minimum interval,
            // so allow well over that.
            TestUtils.waitForCondition(() -> {
                consumer1.poll(Duration.ofMillis(100));
                consumer2.poll(Duration.ofMillis(100));
                return consumer1.assignment().equals(all);
            }, 45_000L, () -> "Partition released by member 2 was never 
reassigned to member 1. " +
                "member1=" + consumer1.assignment() + " member2=" + 
consumer2.assignment() +
                " (group epoch was not bumped after the new regex resolved to 
no topics)");
        }
    }
{code}
 

> Switching to a subscription regex that matches no topic doesn't trigger 
> rebalance
> ---------------------------------------------------------------------------------
>
>                 Key: KAFKA-21409
>                 URL: https://issues.apache.org/jira/browse/KAFKA-21409
>             Project: Kafka
>          Issue Type: Bug
>            Reporter: Chia-Ping Tsai
>            Assignee: Chia-Ping Tsai
>            Priority: Major
>
>  
> {code:java}
> ResolvedRegularExpression newResolvedRegularExpression = entry.getValue();
> ResolvedRegularExpression oldResolvedRegularExpression = group
>   .resolvedRegularExpression(regex)
>   .orElse(ResolvedRegularExpression.EMPTY);                
> if 
> (!oldResolvedRegularExpression.topics().equals(newResolvedRegularExpression.topics()))
>  {
> {code}
> Since ResolvedRegularExpression.EMPTY has no topics which is equal to 
> "match-to-nothing", the condition won't get passed. The side effect is that 
> the partitions won't be reassigned to other consumers.
>  



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to