@@ -13,7 +13,7 @@ use tracing::{debug, instrument, warn};
1313/// caching it with a long TTL saves a per-cycle `DescribeConfigs` over the
1414/// monitored topic set. On each cycle the collector asks the cache which
1515/// topics still need to be queried fresh, then merges the cached-true
16- /// entries with whatever DescribeConfigs returns.
16+ /// entries with whatever ` DescribeConfigs` returns.
1717struct CompactedTopicsCache {
1818 ttl : Duration ,
1919 // (is_compacted, fetched_at). Mutex is fine — accessed only from
@@ -31,10 +31,13 @@ impl CompactedTopicsCache {
3131
3232 /// Split `monitored_topics` into:
3333 /// - `cached_compacted` — topics the cache says are compacted (fresh)
34- /// - `to_fetch` — topics with no fresh cache entry (need DescribeConfigs)
34+ /// - `to_fetch` — topics with no fresh cache entry (need ` DescribeConfigs` )
3535 fn partition < ' a > ( & self , monitored_topics : & ' a [ String ] ) -> ( HashSet < String > , Vec < & ' a str > ) {
3636 let now = Instant :: now ( ) ;
37- let entries = self . entries . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
37+ let entries = self
38+ . entries
39+ . lock ( )
40+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
3841
3942 let mut cached_compacted = HashSet :: new ( ) ;
4043 let mut to_fetch: Vec < & str > = Vec :: new ( ) ;
@@ -55,7 +58,10 @@ impl CompactedTopicsCache {
5558 /// in `fetched_topics`, record whether it appeared in `compacted_result`.
5659 fn update ( & self , fetched_topics : & [ & str ] , compacted_result : & HashSet < String > ) {
5760 let now = Instant :: now ( ) ;
58- let mut entries = self . entries . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
61+ let mut entries = self
62+ . entries
63+ . lock ( )
64+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
5965 for topic in fetched_topics {
6066 let is_compacted = compacted_result. contains ( * topic) ;
6167 entries. insert ( ( * topic) . to_string ( ) , ( is_compacted, now) ) ;
@@ -64,8 +70,14 @@ impl CompactedTopicsCache {
6470
6571 /// Drop cache entries for topics no longer being monitored.
6672 fn prune_to ( & self , monitored_topics : & [ String ] ) {
67- let keep: HashSet < & str > = monitored_topics. iter ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ;
68- let mut entries = self . entries . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
73+ let keep: HashSet < & str > = monitored_topics
74+ . iter ( )
75+ . map ( std:: string:: String :: as_str)
76+ . collect ( ) ;
77+ let mut entries = self
78+ . entries
79+ . lock ( )
80+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
6981 entries. retain ( |k, _| keep. contains ( k. as_str ( ) ) ) ;
7082 }
7183}
@@ -84,7 +96,7 @@ struct MetadataCache {
8496}
8597
8698impl MetadataCache {
87- fn new ( ttl : Duration ) -> Self {
99+ const fn new ( ttl : Duration ) -> Self {
88100 Self {
89101 ttl,
90102 entry : Mutex :: new ( None ) ,
@@ -95,7 +107,10 @@ impl MetadataCache {
95107 if self . ttl . is_zero ( ) {
96108 return None ;
97109 }
98- let guard = self . entry . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
110+ let guard = self
111+ . entry
112+ . lock ( )
113+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
99114 let ( set, at) = guard. as_ref ( ) ?;
100115 if at. elapsed ( ) < self . ttl {
101116 Some ( ( Arc :: clone ( & set. 0 ) , Arc :: clone ( & set. 1 ) ) )
@@ -111,7 +126,10 @@ impl MetadataCache {
111126 fn set ( & self , partitions : Vec < TopicPartition > , topics : Vec < String > ) -> MonitoredSet {
112127 let set: MonitoredSet = ( Arc :: new ( partitions) , Arc :: new ( topics) ) ;
113128 if !self . ttl . is_zero ( ) {
114- let mut guard = self . entry . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
129+ let mut guard = self
130+ . entry
131+ . lock ( )
132+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
115133 * guard = Some ( ( ( Arc :: clone ( & set. 0 ) , Arc :: clone ( & set. 1 ) ) , Instant :: now ( ) ) ) ;
116134 }
117135 set
@@ -129,7 +147,7 @@ struct ConsumerGroupsCache {
129147}
130148
131149impl ConsumerGroupsCache {
132- fn new ( ttl : Duration ) -> Self {
150+ const fn new ( ttl : Duration ) -> Self {
133151 Self {
134152 ttl,
135153 entry : Mutex :: new ( None ) ,
@@ -140,7 +158,10 @@ impl ConsumerGroupsCache {
140158 if self . ttl . is_zero ( ) {
141159 return None ;
142160 }
143- let guard = self . entry . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
161+ let guard = self
162+ . entry
163+ . lock ( )
164+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
144165 let ( groups, at) = guard. as_ref ( ) ?;
145166 if at. elapsed ( ) < self . ttl {
146167 Some ( Arc :: clone ( groups) )
@@ -152,7 +173,10 @@ impl ConsumerGroupsCache {
152173 fn set ( & self , groups : Vec < ConsumerGroupInfo > ) -> Arc < Vec < ConsumerGroupInfo > > {
153174 let arc = Arc :: new ( groups) ;
154175 if !self . ttl . is_zero ( ) {
155- let mut guard = self . entry . lock ( ) . unwrap_or_else ( |p| p. into_inner ( ) ) ;
176+ let mut guard = self
177+ . entry
178+ . lock ( )
179+ . unwrap_or_else ( std:: sync:: PoisonError :: into_inner) ;
156180 * guard = Some ( ( Arc :: clone ( & arc) , Instant :: now ( ) ) ) ;
157181 }
158182 arc
@@ -190,7 +214,7 @@ pub struct OffsetsSnapshot {
190214 /// Topics configured with `cleanup.policy=compact`. Populated by
191215 /// `collect_parallel` for the monitored topic set. Used by the lag
192216 /// calculator to suppress data-loss warnings on compacted topics (where
193- /// low_watermark ahead of committed_offset is expected, not a loss).
217+ /// ` low_watermark` ahead of ` committed_offset` is expected, not a loss).
194218 pub compacted_topics : HashSet < String > ,
195219 #[ allow( dead_code) ]
196220 pub timestamp_ms : i64 ,
@@ -238,15 +262,15 @@ impl OffsetCollector {
238262 /// the watermark + compacted-topic-config path.
239263 ///
240264 /// Per-cycle RPC count:
241- /// - 2 batched ListOffsets calls (EARLIEST + LATEST), routed per leader
265+ /// - 2 batched ` ListOffsets` calls (EARLIEST + LATEST), routed per leader
242266 /// broker internally — O(brokers) broker round trips regardless of
243267 /// partition count.
244- /// - `ceil(groups / 100)` batched DescribeConsumerGroups calls.
245- /// - 1 ListConsumerGroupOffsets call per group (`PER_CALL_CHUNK = 1`
268+ /// - `ceil(groups / 100)` batched ` DescribeConsumerGroups` calls.
269+ /// - 1 ` ListConsumerGroupOffsets` call per group (`PER_CALL_CHUNK = 1`
246270 /// in `fetch_all_group_offsets_batched` because librdkafka 2.12
247271 /// rejects multi-group calls at the client layer; fanned out via
248272 /// `max_concurrent_groups`).
249- /// - 1 DescribeConfigs call restricted to monitored topics.
273+ /// - 1 ` DescribeConfigs` call restricted to monitored topics.
250274 #[ instrument( skip( self ) , fields( cluster = %self . client. cluster_name( ) ) ) ]
251275 pub async fn collect_parallel ( & self ) -> Result < OffsetsSnapshot > {
252276 let start = std:: time:: Instant :: now ( ) ;
@@ -350,13 +374,21 @@ impl OffsetCollector {
350374 // refresh new topics (or nothing at all in steady state).
351375 let phase_start = std:: time:: Instant :: now ( ) ;
352376 let ( mut compacted_topics, to_fetch) = self . compacted_cache . partition ( & monitored_topics) ;
353- if !to_fetch. is_empty ( ) {
377+ if to_fetch. is_empty ( ) {
378+ debug ! (
379+ cached = compacted_topics. len( ) ,
380+ "Compacted-topic cache fully hit — no DescribeConfigs RPC"
381+ ) ;
382+ } else {
354383 debug ! (
355384 to_fetch = to_fetch. len( ) ,
356385 cached = compacted_topics. len( ) ,
357386 "Compacted-topic cache partial miss — refreshing"
358387 ) ;
359- let to_fetch_owned: Vec < String > = to_fetch. iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ;
388+ let to_fetch_owned: Vec < String > = to_fetch
389+ . iter ( )
390+ . map ( std:: string:: ToString :: to_string)
391+ . collect ( ) ;
360392 match self
361393 . client
362394 . fetch_compacted_topics_for ( & to_fetch_owned)
@@ -368,11 +400,6 @@ impl OffsetCollector {
368400 }
369401 Err ( e) => warn ! ( error = %e, "Failed to refresh compacted topics" ) ,
370402 }
371- } else {
372- debug ! (
373- cached = compacted_topics. len( ) ,
374- "Compacted-topic cache fully hit — no DescribeConfigs RPC"
375- ) ;
376403 }
377404 // Drop cache entries for topics no longer monitored (filter change,
378405 // topic deletion) so memory doesn't grow unboundedly.
@@ -472,9 +499,9 @@ impl OffsetCollector {
472499 /// Fetch offsets for all groups via batched Admin API.
473500 ///
474501 /// librdkafka 2.12's `rd_kafka_ListConsumerGroupOffsets` rejects calls with
475- /// more than one group per call ("Exactly one ListConsumerGroupOffsets must
502+ /// more than one group per call ("Exactly one ` ListConsumerGroupOffsets` must
476503 /// be passed") even though the Kafka protocol supports multi-group
477- /// ListOffsetFetch (KIP-709). We therefore issue one FFI call per group,
504+ /// ` ListOffsetFetch` (KIP-709). We therefore issue one FFI call per group,
478505 /// fanned out with bounded concurrency via `max_concurrent_groups`.
479506 ///
480507 /// The win vs. the prior path is not "multi-group in one call" but:
@@ -543,10 +570,10 @@ impl OffsetCollector {
543570 match r {
544571 Ok ( ( _gid, Ok ( Ok ( map) ) ) ) => merged. extend ( map) ,
545572 Ok ( ( gid, Ok ( Err ( e) ) ) ) => {
546- warn ! ( group = %gid, error = %e, "Group-offset call failed" )
573+ warn ! ( group = %gid, error = %e, "Group-offset call failed" ) ;
547574 }
548575 Ok ( ( gid, Err ( e) ) ) => {
549- warn ! ( group = %gid, error = %e, "Group-offset call task panicked" )
576+ warn ! ( group = %gid, error = %e, "Group-offset call task panicked" ) ;
550577 }
551578 Err ( e) => warn ! ( error = %e, "Group-offset join error" ) ,
552579 }
0 commit comments