17
17
18
18
use std:: collections:: HashMap ;
19
19
use std:: collections:: HashSet ;
20
+ use std:: fmt:: Display ;
20
21
use std:: ops:: Deref ;
21
22
use std:: sync:: Arc ;
22
23
@@ -27,24 +28,46 @@ use rocketmq_common::utils::serde_json_utils::SerdeJsonUtils;
27
28
use rocketmq_common:: TimeUtils :: get_current_millis;
28
29
use serde:: Deserialize ;
29
30
use serde:: Serialize ;
31
+ use tracing:: info;
30
32
use tracing:: warn;
31
33
32
34
use crate :: broker_path_config_helper:: get_consumer_order_info_path;
33
35
use crate :: offset:: manager:: consumer_order_info_lock_manager:: ConsumerOrderInfoLockManager ;
36
+ use crate :: subscription:: manager:: subscription_group_manager:: SubscriptionGroupManager ;
37
+ use crate :: topic:: manager:: topic_config_manager:: TopicConfigManager ;
34
38
35
39
const TOPIC_GROUP_SEPARATOR : & str = "@" ;
36
40
const CLEAN_SPAN_FROM_LAST : u64 = 24 * 3600 * 1000 ;
37
41
38
- #[ derive( Default ) ]
39
- pub ( crate ) struct ConsumerOrderInfoManager {
42
+ pub ( crate ) struct ConsumerOrderInfoManager < MS > {
40
43
pub ( crate ) broker_config : Arc < BrokerConfig > ,
41
44
pub ( crate ) consumer_order_info_wrapper : parking_lot:: Mutex < ConsumerOrderInfoWrapper > ,
42
45
pub ( crate ) consumer_order_info_lock_manager : Option < ConsumerOrderInfoLockManager > ,
46
+ pub ( crate ) topic_config_manager : Arc < TopicConfigManager > ,
47
+ pub ( crate ) subscription_group_manager : Arc < SubscriptionGroupManager < MS > > ,
48
+ }
49
+
50
+ impl < MS > ConsumerOrderInfoManager < MS > {
51
+ pub fn new (
52
+ broker_config : Arc < BrokerConfig > ,
53
+ topic_config_manager : Arc < TopicConfigManager > ,
54
+ subscription_group_manager : Arc < SubscriptionGroupManager < MS > > ,
55
+ ) -> ConsumerOrderInfoManager < MS > {
56
+ Self {
57
+ broker_config,
58
+ consumer_order_info_wrapper : parking_lot:: Mutex :: new (
59
+ ConsumerOrderInfoWrapper :: default ( ) ,
60
+ ) ,
61
+ consumer_order_info_lock_manager : None ,
62
+ topic_config_manager,
63
+ subscription_group_manager,
64
+ }
65
+ }
43
66
}
44
67
45
68
//Fully implemented will be removed
46
69
#[ allow( unused_variables) ]
47
- impl ConfigManager for ConsumerOrderInfoManager {
70
+ impl < MS > ConfigManager for ConsumerOrderInfoManager < MS > {
48
71
fn config_file_path ( & self ) -> String {
49
72
get_consumer_order_info_path ( self . broker_config . store_path_root_dir . as_str ( ) )
50
73
}
@@ -81,8 +104,92 @@ impl ConfigManager for ConsumerOrderInfoManager {
81
104
}
82
105
}
83
106
84
- impl ConsumerOrderInfoManager {
85
- fn auto_clean ( & self ) { }
107
+ impl < MS > ConsumerOrderInfoManager < MS > {
108
+ pub fn auto_clean ( & self ) {
109
+ let mut consumer_order_info_wrapper = self . consumer_order_info_wrapper . lock ( ) ;
110
+ let table = & mut consumer_order_info_wrapper. table ;
111
+
112
+ // Iterate through the `table` entries (topic@group -> queueId -> OrderInfo)
113
+ let mut keys_to_remove = Vec :: new ( ) ; // Temporary storage for keys to remove
114
+
115
+ for ( topic_at_group, qs) in table. iter_mut ( ) {
116
+ let arrays: Vec < & str > = topic_at_group. split ( '@' ) . collect ( ) ;
117
+ if arrays. len ( ) != 2 {
118
+ continue ;
119
+ }
120
+ let topic = arrays[ 0 ] ;
121
+ let group = arrays[ 1 ] ;
122
+
123
+ let topic_config = self
124
+ . topic_config_manager
125
+ . select_topic_config ( & CheetahString :: from ( topic) ) ;
126
+ if topic_config. is_none ( ) {
127
+ info ! (
128
+ "Topic not exist, Clean order info, {}:{:?}" ,
129
+ topic_at_group, qs
130
+ ) ;
131
+ keys_to_remove. push ( topic_at_group. clone ( ) ) ;
132
+ continue ;
133
+ }
134
+ let subscription_group_wrapper = self
135
+ . subscription_group_manager
136
+ . subscription_group_wrapper ( )
137
+ . lock ( ) ;
138
+ let subscription_group_config = subscription_group_wrapper
139
+ . subscription_group_table ( )
140
+ . get ( & CheetahString :: from ( group) ) ;
141
+ if subscription_group_config. is_none ( ) {
142
+ info ! (
143
+ "Group not exist, Clean order info, {}:{:?}" ,
144
+ topic_at_group, qs
145
+ ) ;
146
+ keys_to_remove. push ( topic_at_group. clone ( ) ) ;
147
+ continue ;
148
+ }
149
+
150
+ if qs. is_empty ( ) {
151
+ info ! (
152
+ "Order table is empty, Clean order info, {}:{:?}" ,
153
+ topic_at_group, qs
154
+ ) ;
155
+ keys_to_remove. push ( topic_at_group. clone ( ) ) ;
156
+ continue ;
157
+ }
158
+ let topic_config = topic_config. unwrap ( ) ;
159
+ // Clean individual queues in the current topic@group
160
+ let mut queues_to_remove = Vec :: new ( ) ;
161
+ for ( queue_id, order_info) in qs. iter_mut ( ) {
162
+ if * queue_id == topic_config. read_queue_nums as i32 {
163
+ queues_to_remove. push ( * queue_id) ;
164
+ info ! (
165
+ "Queue not exist, Clean order info, {}:{}, {}" ,
166
+ topic_at_group, order_info, topic_config
167
+ ) ;
168
+ continue ;
169
+ }
170
+ }
171
+
172
+ // Remove stale or invalid queues
173
+ for queue_id in queues_to_remove {
174
+ qs. remove ( & queue_id) ;
175
+ info ! (
176
+ "Removed queue {} for topic@group {}" ,
177
+ queue_id, topic_at_group
178
+ ) ;
179
+ }
180
+
181
+ // If all queues are removed, mark topic@group for removal
182
+ if qs. is_empty ( ) {
183
+ keys_to_remove. push ( topic_at_group. clone ( ) ) ;
184
+ }
185
+ }
186
+
187
+ // Now, remove all topics/groups from the table that need to be cleaned
188
+ for key in keys_to_remove {
189
+ table. remove ( & key) ;
190
+ info ! ( "Removed topic@group {}" , key) ;
191
+ }
192
+ }
86
193
87
194
pub fn update_next_visible_time (
88
195
& self ,
@@ -167,6 +274,25 @@ pub(crate) struct OrderInfo {
167
274
attempt_id : String ,
168
275
}
169
276
277
+ impl Display for OrderInfo {
278
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
279
+ write ! (
280
+ f,
281
+ "OrderInfo {{ popTime: {}, invisibleTime: {:?}, offsetList: {:?}, \
282
+ offsetNextVisibleTime: {:?}, offsetConsumedCount: {:?}, lastConsumeTimestamp: {}, \
283
+ commitOffsetBit: {}, attemptId: {} }}",
284
+ self . pop_time,
285
+ self . invisible_time,
286
+ self . offset_list,
287
+ self . offset_next_visible_time,
288
+ self . offset_consumed_count,
289
+ self . last_consume_timestamp,
290
+ self . commit_offset_bit,
291
+ self . attempt_id
292
+ )
293
+ }
294
+ }
295
+
170
296
impl OrderInfo {
171
297
/// Builds a list of offsets from a given list of queue offsets.
172
298
/// If the list contains only one element, it returns the same list.
0 commit comments