17
17
18
18
use std:: {
19
19
collections:: { HashMap , HashSet } ,
20
- time:: SystemTime ,
20
+ time:: { Duration , SystemTime } ,
21
21
} ;
22
22
23
23
use rocketmq_common:: common:: {
24
24
config:: TopicConfig , constant:: PermName , mix_all, namesrv:: namesrv_config:: NamesrvConfig ,
25
25
topic:: TopicValidator ,
26
26
} ;
27
- use rocketmq_remoting:: protocol:: {
28
- body:: {
29
- broker_body:: cluster_info:: ClusterInfo ,
30
- topic_info_wrapper:: topic_config_wrapper:: TopicConfigAndMappingSerializeWrapper ,
27
+ use rocketmq_remoting:: {
28
+ clients:: RemoteClient ,
29
+ code:: request_code:: RequestCode ,
30
+ protocol:: {
31
+ body:: {
32
+ broker_body:: cluster_info:: ClusterInfo ,
33
+ topic_info_wrapper:: topic_config_wrapper:: TopicConfigAndMappingSerializeWrapper ,
34
+ } ,
35
+ header:: namesrv:: brokerid_change_request_header:: NotifyMinBrokerIdChangeRequestHeader ,
36
+ namesrv:: RegisterBrokerResult ,
37
+ remoting_command:: RemotingCommand ,
38
+ route:: route_data_view:: { BrokerData , QueueData , TopicRouteData } ,
39
+ static_topic:: topic_queue_info:: TopicQueueMappingInfo ,
40
+ DataVersion ,
31
41
} ,
32
- namesrv:: RegisterBrokerResult ,
33
- route:: route_data_view:: { BrokerData , QueueData , TopicRouteData } ,
34
- static_topic:: topic_queue_info:: TopicQueueMappingInfo ,
35
- DataVersion ,
36
42
} ;
37
43
use tracing:: { debug, info, warn} ;
38
44
@@ -52,13 +58,14 @@ type TopicQueueMappingInfoTable =
52
58
53
59
#[ derive( Debug , Clone , Default ) ]
54
60
pub struct RouteInfoManager {
55
- topic_queue_table : TopicQueueTable ,
56
- broker_addr_table : BrokerAddrTable ,
57
- cluster_addr_table : ClusterAddrTable ,
58
- broker_live_table : BrokerLiveTable ,
59
- filter_server_table : FilterServerTable ,
60
- topic_queue_mapping_info_table : TopicQueueMappingInfoTable ,
61
- namesrv_config : NamesrvConfig ,
61
+ pub ( crate ) topic_queue_table : TopicQueueTable ,
62
+ pub ( crate ) broker_addr_table : BrokerAddrTable ,
63
+ pub ( crate ) cluster_addr_table : ClusterAddrTable ,
64
+ pub ( crate ) broker_live_table : BrokerLiveTable ,
65
+ pub ( crate ) filter_server_table : FilterServerTable ,
66
+ pub ( crate ) topic_queue_mapping_info_table : TopicQueueMappingInfoTable ,
67
+ pub ( crate ) namesrv_config : NamesrvConfig ,
68
+ pub ( crate ) remote_client : RemoteClient ,
62
69
}
63
70
64
71
#[ allow( private_interfaces) ]
@@ -76,6 +83,7 @@ impl RouteInfoManager {
76
83
filter_server_table : HashMap :: new ( ) ,
77
84
topic_queue_mapping_info_table : HashMap :: new ( ) ,
78
85
namesrv_config,
86
+ remote_client : RemoteClient :: new ( ) ,
79
87
}
80
88
}
81
89
}
@@ -106,26 +114,26 @@ impl RouteInfoManager {
106
114
. unwrap ( )
107
115
. insert ( broker_name. clone ( ) ) ;
108
116
109
- let is_old_version_broker = if let Some ( value) = enable_acting_master {
117
+ let enable_acting_master_inner = if let Some ( value) = enable_acting_master {
110
118
value
111
119
} else {
112
120
false
113
121
} ;
114
122
let mut register_first =
115
123
if let Some ( broker_data) = self . broker_addr_table . get_mut ( & broker_name) {
116
- broker_data. set_enable_acting_master ( is_old_version_broker ) ;
124
+ broker_data. set_enable_acting_master ( enable_acting_master_inner ) ;
117
125
broker_data. set_zone_name ( zone_name. clone ( ) ) ;
118
126
false
119
127
} else {
120
- self . broker_addr_table . insert (
128
+ let mut broker_data = BrokerData :: new (
129
+ cluster_name. clone ( ) ,
121
130
broker_name. clone ( ) ,
122
- BrokerData :: new (
123
- cluster_name. clone ( ) ,
124
- broker_name. clone ( ) ,
125
- HashMap :: new ( ) ,
126
- zone_name,
127
- ) ,
131
+ HashMap :: new ( ) ,
132
+ zone_name,
128
133
) ;
134
+ broker_data. set_enable_acting_master ( enable_acting_master_inner) ;
135
+ self . broker_addr_table
136
+ . insert ( broker_name. clone ( ) , broker_data) ;
129
137
true
130
138
} ;
131
139
let broker_data = self . broker_addr_table . get_mut ( & broker_name) . unwrap ( ) ;
@@ -142,18 +150,31 @@ impl RouteInfoManager {
142
150
// IP:PORT> The same IP:PORT must only have one record in brokerAddrTable
143
151
broker_data. remove_broker_by_addr ( broker_id, & broker_addr) ;
144
152
153
+ //If Local brokerId stateVersion bigger than the registering one
145
154
if let Some ( old_broker_addr) = broker_data. broker_addrs ( ) . get ( & broker_id) {
146
155
if old_broker_addr != & broker_addr {
147
- let addr_info =
156
+ let addr_info_old =
148
157
BrokerAddrInfo :: new ( cluster_name. clone ( ) , old_broker_addr. to_string ( ) ) ;
149
- if let Some ( val) = self . broker_live_table . get ( & addr_info ) {
158
+ if let Some ( val) = self . broker_live_table . get ( & addr_info_old ) {
150
159
let old_state_version = val. data_version ( ) . state_version ( ) ;
151
160
let new_state_version = topic_config_serialize_wrapper
152
161
. data_version ( )
153
162
. as_ref ( )
154
163
. unwrap ( )
155
164
. state_version ( ) ;
156
165
if old_state_version > new_state_version {
166
+ warn ! (
167
+ "Registered Broker conflicts with the existed one, just ignore.: \
168
+ Cluster:{}, BrokerName:{}, BrokerId:{},Old BrokerAddr:{}, Old \
169
+ Version:{}, New BrokerAddr:{}, New Version:{}.",
170
+ & cluster_name,
171
+ & broker_name,
172
+ broker_id,
173
+ old_broker_addr,
174
+ old_state_version,
175
+ & broker_addr,
176
+ new_state_version
177
+ ) ;
157
178
self . broker_live_table . remove (
158
179
BrokerAddrInfo :: new ( cluster_name. clone ( ) , broker_addr. clone ( ) ) . as_ref ( ) ,
159
180
) ;
@@ -184,14 +205,18 @@ impl RouteInfoManager {
184
205
register_first |= old_addr. is_none ( ) ;
185
206
let is_master = mix_all:: MASTER_ID == broker_id as u64 ;
186
207
187
- let is_prime_slave = !is_old_version_broker
208
+ let is_prime_slave = enable_acting_master . is_some ( )
188
209
&& !is_master
189
210
&& broker_id == broker_data. broker_addrs ( ) . keys ( ) . min ( ) . copied ( ) . unwrap ( ) ;
190
211
let broker_data = broker_data. clone ( ) ;
212
+ //handle master or prime slave topic config update
191
213
if is_master || is_prime_slave {
192
214
if let Some ( tc_table) = topic_config_serialize_wrapper. topic_config_table ( ) {
193
215
let topic_queue_mapping_info_map =
194
216
topic_config_serialize_wrapper. topic_queue_mapping_info_map ( ) ;
217
+
218
+ // Delete the topics that don't exist in tcTable from the current broker
219
+ // Static topic is not supported currently
195
220
if self . namesrv_config . delete_topic_with_broker_registration
196
221
&& topic_queue_mapping_info_map. is_empty ( )
197
222
{
@@ -284,7 +309,7 @@ impl RouteInfoManager {
284
309
self . filter_server_table . remove ( & broker_addr_info) ;
285
310
} else {
286
311
self . filter_server_table
287
- . insert ( broker_addr_info, filter_server_list) ;
312
+ . insert ( broker_addr_info. clone ( ) , filter_server_list) ;
288
313
}
289
314
290
315
if mix_all:: MASTER_ID != broker_id as u64 {
@@ -300,7 +325,17 @@ impl RouteInfoManager {
300
325
}
301
326
}
302
327
if is_min_broker_id_changed && self . namesrv_config . notify_min_broker_id_changed {
303
- todo ! ( )
328
+ self . notify_min_broker_id_changed (
329
+ broker_data. broker_addrs ( ) ,
330
+ None ,
331
+ Some (
332
+ self . broker_live_table
333
+ . get ( & broker_addr_info)
334
+ . unwrap ( )
335
+ . ha_server_addr ( )
336
+ . to_string ( ) ,
337
+ ) ,
338
+ )
304
339
}
305
340
Some ( result)
306
341
}
@@ -526,4 +561,56 @@ impl RouteInfoManager {
526
561
. insert ( topic_config. topic_name . clone ( ) , queue_data_map_inner) ;
527
562
}
528
563
}
564
+
565
+ fn notify_min_broker_id_changed (
566
+ & mut self ,
567
+ broker_addr_map : & HashMap < i64 , String > ,
568
+ offline_broker_addr : Option < String > ,
569
+ ha_broker_addr : Option < String > ,
570
+ ) {
571
+ if broker_addr_map. is_empty ( ) {
572
+ return ;
573
+ }
574
+ let min_broker_id = broker_addr_map. keys ( ) . min ( ) . copied ( ) . unwrap ( ) ;
575
+ // notify master
576
+ let request_header = NotifyMinBrokerIdChangeRequestHeader :: new (
577
+ Some ( min_broker_id) ,
578
+ None ,
579
+ broker_addr_map. get ( & min_broker_id) . cloned ( ) ,
580
+ offline_broker_addr. clone ( ) ,
581
+ ha_broker_addr,
582
+ ) ;
583
+
584
+ if let Some ( broker_addrs_notify) =
585
+ self . choose_broker_addrs_to_notify ( broker_addr_map, offline_broker_addr)
586
+ {
587
+ for broker_addr in broker_addrs_notify {
588
+ let _ = self . remote_client . invoke_oneway (
589
+ broker_addr,
590
+ RemotingCommand :: create_request_command (
591
+ RequestCode :: NotifyMinBrokerIdChange ,
592
+ request_header. clone ( ) ,
593
+ ) ,
594
+ Duration :: from_millis ( 3000 ) ,
595
+ ) ;
596
+ }
597
+ }
598
+ }
599
+
600
+ fn choose_broker_addrs_to_notify (
601
+ & mut self ,
602
+ broker_addr_map : & HashMap < i64 , String > ,
603
+ offline_broker_addr : Option < String > ,
604
+ ) -> Option < Vec < String > > {
605
+ if broker_addr_map. len ( ) == 1 || offline_broker_addr. is_some ( ) {
606
+ return Some ( broker_addr_map. values ( ) . cloned ( ) . collect ( ) ) ;
607
+ }
608
+ let min_broker_id = broker_addr_map. keys ( ) . min ( ) . copied ( ) . unwrap ( ) ;
609
+ let broker_addr_vec = broker_addr_map
610
+ . iter ( )
611
+ . filter ( |( key, _value) | * * key != min_broker_id)
612
+ . map ( |( _, value) | value. clone ( ) )
613
+ . collect ( ) ;
614
+ Some ( broker_addr_vec)
615
+ }
529
616
}
0 commit comments