Repository: apache/kafka
File: group-coordinator/src/main/java/org/apache/kafka/coordinator/group/GroupMetadataManager.java (Java)

Code before:
        boolean subscribedTopicRegexChanged = !Objects.equals(oldSubscribedTopicRegex, newSubscribedTopicRegex);
        if (subscribedTopicRegexChanged) {
            log.debug("[GroupId {}] Member {} updated its subscribed regex to: {}.",
                groupId, memberId, newSubscribedTopicRegex);

            updateRegularExpressionsResult = UpdateRegularExpressionsResult.REGEX_UPDATED;

            if (isNotEmpty(oldSubscribedTopicRegex) && group.numSubscribedMembers(oldSubscribedTopicRegex) == 1) {
                // If the member was the last one subscribed to the regex, we delete the
                // resolved regular expression.
                records.add(newConsumerGroupRegularExpressionTombstone(
                    groupId,
                    oldSubscribedTopicRegex
                ));
            }

            if (isNotEmpty(newSubscribedTopicRegex)) {
                if (group.numSubscribedMembers(newSubscribedTopicRegex) == 0) {
                    // If the member subscribed to a new regex, we compile it to ensure its validity.
                    // We also trigger a refresh of the regexes in order to resolve it.
                    throwIfRegularExpressionIsInvalid(updatedMember.subscribedTopicRegex());
                    requireRefresh = true;

                    if (isNotEmpty(oldSubscribedTopicRegex) && group.numSubscribedMembers(oldSubscribedTopicRegex) != 0) {
                        updateRegularExpressionsResult = UpdateRegularExpressionsResult.REGEX_UPDATED_AND_RESOLVED;
                    }
                } else {
                    // If the new regex is already resolved, we trigger a rebalance
                    // by bumping the group epoch.
                    if (group.resolvedRegularExpression(newSubscribedTopicRegex).isPresent()) {
                        updateRegularExpressionsResult = UpdateRegularExpressionsResult.REGEX_UPDATED_AND_RESOLVED;
                    }
                }
            }
        }

        // Conditions to trigger a refresh:
        // 0.   The group is subscribed to regular expressions.
        // 1.   There is no ongoing refresh for the group.
        // 2.   The last refresh is older than 10s.
        // 3.1  The group has unresolved regular expressions.
        // 3.2  Or the metadata image has new topics.
        // 3.3  Or the last refresh is older than the batch refresh max interval.

        // 0. The group is subscribed to regular expressions. We also take the one
        //    that the current may have just introduced.
        if (!requireRefresh && group.subscribedRegularExpressions().isEmpty()) {
            return updateRegularExpressionsResult;
        }

        // 1. There is no ongoing refresh for the group.

Review comment (bug):
We're changing the return value in the wrong branch of the code. We want the branch where `newSubscribedTopicRegex` is empty.

Code after:
        boolean subscribedTopicRegexChanged = !Objects.equals(oldSubscribedTopicRegex, newSubscribedTopicRegex);
        if (subscribedTopicRegexChanged) {
            log.debug("[GroupId {}] Member {} updated its subscribed regex to: {}.",
                groupId, memberId, newSubscribedTopicRegex);

            updateRegularExpressionsResult = UpdateRegularExpressionsResult.REGEX_UPDATED;

            if (isNotEmpty(oldSubscribedTopicRegex) && group.numSubscribedMembers(oldSubscribedTopicRegex) == 1) {
                // If the member was the last one subscribed to the regex, we delete the
                // resolved regular expression.
                records.add(newConsumerGroupRegularExpressionTombstone(
                    groupId,
                    oldSubscribedTopicRegex
                ));
            }

            if (isNotEmpty(newSubscribedTopicRegex)) {
                if (group.numSubscribedMembers(newSubscribedTopicRegex) == 0) {
                    // If the member subscribed to a new regex, we compile it to ensure its validity.
                    // We also trigger a refresh of the regexes in order to resolve it.
                    throwIfRegularExpressionIsInvalid(updatedMember.subscribedTopicRegex());
                    requireRefresh = true;
                } else {
                    // If the new regex is already resolved, we trigger a rebalance
                    // by bumping the group epoch.
                    if (group.resolvedRegularExpression(newSubscribedTopicRegex).isPresent()) {
                        updateRegularExpressionsResult = UpdateRegularExpressionsResult.REGEX_UPDATED_AND_RESOLVED;
                    }
                }
            } else if (isNotEmpty(oldSubscribedTopicRegex)) {
                updateRegularExpressionsResult = UpdateRegularExpressionsResult.REGEX_UPDATED_AND_RESOLVED;
            }
        }

        // Conditions to trigger a refresh:
        // 0.   The group is subscribed to regular expressions.
        // 1.   There is no ongoing refresh for the group.
        // 2.   The last refresh is older than 10s.
        // 3.1  The group has unresolved regular expressions.
        // 3.2  Or the metadata image has new topics.
        // 3.3  Or the last refresh is older than the batch refresh max interval.

        // 0. The group is subscribed to regular expressions. We also take the one
        //    that the current may have just introduced.
        if (!requireRefresh && group.subscribedRegularExpressions().isEmpty()) {
            return updateRegularExpressionsResult;
        }

        // 1. There is no ongoing refresh for the group.
        String key = group.groupId() + "-regex";
        if (executor.isScheduled(key)) {