@@ -100,10 +100,11 @@ type client struct {
100
100
seedBrokers []* Broker
101
101
deadSeeds []* Broker
102
102
103
- controllerID int32 // cluster controller broker id
104
- brokers map [int32 ]* Broker // maps broker ids to brokers
105
- metadata map [string ]map [int32 ]* PartitionMetadata // maps topics to partition ids to metadata
106
- coordinators map [string ]int32 // Maps consumer group names to coordinating broker IDs
103
+ controllerID int32 // cluster controller broker id
104
+ brokers map [int32 ]* Broker // maps broker ids to brokers
105
+ metadata map [string ]map [int32 ]* PartitionMetadata // maps topics to partition ids to metadata
106
+ metadataTopics map [string ]none // topics that need to collect metadata
107
+ coordinators map [string ]int32 // Maps consumer group names to coordinating broker IDs
107
108
108
109
// If the number of partitions is large, we can get some churn calling cachedPartitions,
109
110
// so the result is cached. It is important to update this value whenever metadata is changed
@@ -136,6 +137,7 @@ func NewClient(addrs []string, conf *Config) (Client, error) {
136
137
closed : make (chan none ),
137
138
brokers : make (map [int32 ]* Broker ),
138
139
metadata : make (map [string ]map [int32 ]* PartitionMetadata ),
140
+ metadataTopics : make (map [string ]none ),
139
141
cachedPartitionsResults : make (map [string ][maxPartitionIndex ][]int32 ),
140
142
coordinators : make (map [string ]int32 ),
141
143
}
@@ -207,6 +209,7 @@ func (client *client) Close() error {
207
209
208
210
client .brokers = nil
209
211
client .metadata = nil
212
+ client .metadataTopics = nil
210
213
211
214
return nil
212
215
}
@@ -231,6 +234,22 @@ func (client *client) Topics() ([]string, error) {
231
234
return ret , nil
232
235
}
233
236
237
+ func (client * client ) MetadataTopics () ([]string , error ) {
238
+ if client .Closed () {
239
+ return nil , ErrClosedClient
240
+ }
241
+
242
+ client .lock .RLock ()
243
+ defer client .lock .RUnlock ()
244
+
245
+ ret := make ([]string , 0 , len (client .metadataTopics ))
246
+ for topic := range client .metadataTopics {
247
+ ret = append (ret , topic )
248
+ }
249
+
250
+ return ret , nil
251
+ }
252
+
234
253
func (client * client ) Partitions (topic string ) ([]int32 , error ) {
235
254
if client .Closed () {
236
255
return nil , ErrClosedClient
@@ -649,7 +668,7 @@ func (client *client) refreshMetadata() error {
649
668
topics := []string {}
650
669
651
670
if ! client .conf .Metadata .Full {
652
- if specificTopics , err := client .Topics (); err != nil {
671
+ if specificTopics , err := client .MetadataTopics (); err != nil {
653
672
return err
654
673
} else if len (specificTopics ) == 0 {
655
674
return ErrNoTopicsToUpdateMetadata
@@ -732,9 +751,16 @@ func (client *client) updateMetadata(data *MetadataResponse, allKnownMetaData bo
732
751
733
752
if allKnownMetaData {
734
753
client .metadata = make (map [string ]map [int32 ]* PartitionMetadata )
754
+ client .metadataTopics = make (map [string ]none )
735
755
client .cachedPartitionsResults = make (map [string ][maxPartitionIndex ][]int32 )
736
756
}
737
757
for _ , topic := range data .Topics {
758
+ // topics must be added firstly to `metadataTopics` to guarantee that all
759
+ // requested topics must be recorded to keep them trackable for periodically
760
+ // metadata refresh.
761
+ if _ , exists := client .metadataTopics [topic .Name ]; ! exists {
762
+ client .metadataTopics [topic .Name ] = none {}
763
+ }
738
764
delete (client .metadata , topic .Name )
739
765
delete (client .cachedPartitionsResults , topic .Name )
740
766
0 commit comments