Skip to content

Commit 195bed8

Browse files
committed
kgo: add ConsumeExcludeTopics
Fixes #1076
1 parent db9ee76 commit 195bed8

2 files changed

Lines changed: 39 additions & 4 deletions

File tree

‎pkg/kgo/config.go‎

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ type cfg struct {
164164

165165
recheckPreferredReplicaInterval time.Duration
166166

167-
topics map[string]*regexp.Regexp // topics to consume; if regex is true, values are compiled regular expressions
168-
partitions map[string]map[int32]Offset // partitions to directly consume from
169-
regex bool
167+
topics map[string]*regexp.Regexp // topics to consume; if regex is true, values are compiled regular expressions
168+
excludeTopics map[string]*regexp.Regexp // topics to exclude; only used if regex is true, values are compiled regular expressions
169+
partitions map[string]map[int32]Offset // partitions to directly consume from
170+
regex bool
170171

171172
////////////////////////////
172173
// CONSUMER GROUP SECTION //
@@ -384,6 +385,15 @@ func (cfg *cfg) validate() error {
384385
}
385386
cfg.topics[re] = compiled
386387
}
388+
for re := range cfg.excludeTopics {
389+
compiled, err := regexp.Compile(re)
390+
if err != nil {
391+
return fmt.Errorf("invalid regular expression %q", re)
392+
}
393+
cfg.excludeTopics[re] = compiled
394+
}
395+
} else if len(cfg.excludeTopics) > 0 {
396+
return errors.New("invalid use of ConsumeExcludeTopics when not using ConsumeRegex")
387397
}
388398

389399
if cfg.topics != nil && cfg.partitions != nil {
@@ -1526,7 +1536,8 @@ func ConsumePartitions(partitions map[string]map[int32]Offset) ConsumerOpt {
15261536
}
15271537

15281538
// ConsumeRegex sets the client to parse all topics passed to ConsumeTopics as
1529-
// regular expressions.
1539+
// regular expressions. You can further use ConsumeExcludeTopics to exclude
1540+
// topics that would match any ConsumeTopics regex.
15301541
//
15311542
// When consuming via regex, every metadata request loads *all* topics, so that
15321543
// all topics can be passed to any regular expressions. Every topic is
@@ -1536,6 +1547,22 @@ func ConsumeRegex() ConsumerOpt {
15361547
return consumerOpt{func(cfg *cfg) { cfg.regex = true }}
15371548
}
15381549

1550+
// ConsumeExcludeTopics sets topics to exclude when using regex consumption.
1551+
// This option only has effect when ConsumeRegex is enabled.
1552+
//
1553+
// Topics matching any of the provided regular expressions will be excluded from
1554+
// consumption, even if they match patterns provided to ConsumeTopics.
1555+
func ConsumeExcludeTopics(topics ...string) ConsumerOpt {
1556+
return consumerOpt{func(cfg *cfg) {
1557+
if cfg.excludeTopics == nil {
1558+
cfg.excludeTopics = make(map[string]*regexp.Regexp, len(topics))
1559+
}
1560+
for _, topic := range topics {
1561+
cfg.excludeTopics[topic] = nil
1562+
}
1563+
}}
1564+
}
1565+
15391566
// DisableFetchSessions sets the client to not use fetch sessions (Kafka 1.0+).
15401567
//
15411568
// A "fetch session" is a way to reduce bandwidth for fetch requests &

‎pkg/kgo/consumer.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,14 @@ func (c *consumer) filterMetadataAllTopics(topics []string) []string {
12391239
break
12401240
}
12411241
}
1242+
if want {
1243+
for _, re := range c.cl.cfg.excludeTopics {
1244+
if re.MatchString(topic) {
1245+
want = false
1246+
break
1247+
}
1248+
}
1249+
}
12421250
if !want {
12431251
rns.skip(topic)
12441252
}

0 commit comments

Comments
 (0)