rocketmq_client_rust/consumer/
default_mq_push_consumer_builder.rs1use std::collections::HashMap;
16use std::sync::Arc;
17
18use cheetah_string::CheetahString;
19use rocketmq_model::common::consumer::consume_from_where::ConsumeFromWhere;
20use rocketmq_protocol::protocol::heartbeat::message_model::MessageModel;
21use rocketmq_transport::api::RPCHook;
22
23use crate::base::client_config::ClientConfig;
24use crate::base::client_options::ClientOptions;
25use crate::consumer::allocate_message_queue_strategy::AllocateMessageQueueStrategy;
26use crate::consumer::default_mq_push_consumer::ConsumerConfig;
27use crate::consumer::default_mq_push_consumer::ConsumerTuningProfile;
28use crate::consumer::default_mq_push_consumer::DefaultMQPushConsumer;
29use crate::consumer::message_queue_listener::ArcMessageQueueListener;
30use crate::nameserver_discovery::NameServerDiscoveryConfig;
31use crate::runtime::ClientRuntime;
32use crate::trace::trace_dispatcher::ArcTraceDispatcher;
33
34pub struct DefaultMQPushConsumerBuilder {
35 client_runtime: Arc<ClientRuntime>,
36 client_config: ClientConfig,
37 nameserver_discovery: Option<NameServerDiscoveryConfig>,
38 consumer_group: Option<CheetahString>,
39 message_model: Option<MessageModel>,
40 consume_from_where: Option<ConsumeFromWhere>,
41 consume_timestamp: Option<CheetahString>,
42 allocate_message_queue_strategy: Option<Arc<dyn AllocateMessageQueueStrategy>>,
43 subscription: Option<Arc<HashMap<CheetahString, CheetahString>>>,
44
45 message_queue_listener: Option<ArcMessageQueueListener>,
46
47 consume_thread_min: Option<u32>,
48 consume_thread_max: Option<u32>,
49 adjust_thread_pool_nums_threshold: Option<u64>,
50 consume_concurrently_max_span: Option<u32>,
51 pull_threshold_for_queue: Option<u32>,
52 pop_threshold_for_queue: Option<u32>,
53 pull_threshold_size_for_queue: Option<u32>,
54 pull_threshold_for_topic: Option<i32>,
55 pull_threshold_size_for_topic: Option<i32>,
56 pull_interval: Option<u64>,
57 consume_message_batch_max_size: Option<u32>,
58 pull_batch_size: Option<u32>,
59 pull_batch_size_in_bytes: Option<u32>,
60 post_subscription_when_pull: Option<bool>,
61 unit_mode: Option<bool>,
62 max_reconsume_times: Option<i32>,
63 suspend_current_queue_time_millis: Option<u64>,
64 consume_timeout: Option<u64>,
65 pop_invisible_time: Option<u64>,
66 pop_batch_nums: Option<u32>,
67 await_termination_millis_when_shutdown: Option<u64>,
68 trace_dispatcher: Option<ArcTraceDispatcher>,
69 client_rebalance: Option<bool>,
70 rpc_hook: Option<Arc<dyn RPCHook>>,
71 tuning_profile: Option<ConsumerTuningProfile>,
72}
73
74impl DefaultMQPushConsumerBuilder {
75 #[must_use]
76 pub fn new(client_runtime: Arc<ClientRuntime>) -> Self {
77 Self {
78 client_runtime,
79 client_config: ClientConfig::default(),
80 nameserver_discovery: None,
81 consumer_group: None,
82 message_model: None,
83 consume_from_where: None,
84 consume_timestamp: None,
85 allocate_message_queue_strategy: None,
86 subscription: None,
87 message_queue_listener: None,
88 consume_thread_min: None,
89 consume_thread_max: None,
90 adjust_thread_pool_nums_threshold: None,
91 consume_concurrently_max_span: None,
92 pull_threshold_for_queue: None,
93 pop_threshold_for_queue: None,
94 pull_threshold_size_for_queue: None,
95 pull_threshold_for_topic: None,
96 pull_threshold_size_for_topic: None,
97 pull_interval: None,
98 consume_message_batch_max_size: None,
99 pull_batch_size: None,
100 pull_batch_size_in_bytes: None,
101 post_subscription_when_pull: None,
102 unit_mode: None,
103 max_reconsume_times: None,
104 suspend_current_queue_time_millis: None,
105 consume_timeout: None,
106 pop_invisible_time: None,
107 pop_batch_nums: None,
108 await_termination_millis_when_shutdown: None,
109 trace_dispatcher: None,
110 client_rebalance: None,
111 rpc_hook: None,
112 tuning_profile: None,
113 }
114 }
115 #[inline]
116 pub fn name_server_addr(mut self, name_server_addr: impl Into<CheetahString>) -> Self {
117 self.client_config.namesrv_addr = Some(name_server_addr.into());
118 self.client_config
119 .namespace_initialized
120 .store(false, std::sync::atomic::Ordering::Release);
121 self
122 }
123
124 #[inline]
125 pub fn client_config(mut self, client_config: ClientConfig) -> Self {
126 self.client_config = client_config;
127 self.nameserver_discovery = None;
128 self
129 }
130
131 #[inline]
132 pub fn client_options(mut self, options: ClientOptions) -> Self {
133 self.client_config = options.client_config().clone();
134 self.nameserver_discovery = options.nameserver_discovery().cloned();
135 self
136 }
137
138 #[inline]
139 pub fn nameserver_discovery(mut self, discovery: NameServerDiscoveryConfig) -> Self {
140 self.nameserver_discovery = Some(discovery);
141 self
142 }
143
144 #[inline]
146 pub fn consumer_group(mut self, consumer_group: impl Into<CheetahString>) -> Self {
147 self.consumer_group = Some(consumer_group.into());
148 self
149 }
150
151 #[inline]
152 pub fn message_model(mut self, message_model: MessageModel) -> Self {
153 self.message_model = Some(message_model);
154 self
155 }
156
157 #[inline]
158 pub fn consume_from_where(mut self, consume_from_where: ConsumeFromWhere) -> Self {
159 self.consume_from_where = Some(consume_from_where);
160 self
161 }
162
163 #[inline]
164 pub fn consume_timestamp(mut self, consume_timestamp: impl Into<CheetahString>) -> Self {
165 self.consume_timestamp = Some(consume_timestamp.into());
166 self
167 }
168
169 #[inline]
170 pub fn allocate_message_queue_strategy(
171 mut self,
172 allocate_message_queue_strategy: Arc<dyn AllocateMessageQueueStrategy>,
173 ) -> Self {
174 self.allocate_message_queue_strategy = Some(allocate_message_queue_strategy);
175 self
176 }
177
178 #[inline]
179 pub fn message_queue_listener(mut self, message_queue_listener: Option<ArcMessageQueueListener>) -> Self {
180 self.message_queue_listener = message_queue_listener;
181 self
182 }
183
184 #[inline]
185 pub fn consume_thread_min(mut self, consume_thread_min: u32) -> Self {
186 self.consume_thread_min = Some(consume_thread_min);
187 self
188 }
189
190 #[inline]
191 pub fn consume_thread_max(mut self, consume_thread_max: u32) -> Self {
192 self.consume_thread_max = Some(consume_thread_max);
193 self
194 }
195
196 #[inline]
197 pub fn adjust_thread_pool_nums_threshold(mut self, adjust_thread_pool_nums_threshold: u64) -> Self {
198 self.adjust_thread_pool_nums_threshold = Some(adjust_thread_pool_nums_threshold);
199 self
200 }
201
202 #[inline]
203 pub fn consume_concurrently_max_span(mut self, consume_concurrently_max_span: u32) -> Self {
204 self.consume_concurrently_max_span = Some(consume_concurrently_max_span);
205 self
206 }
207
208 #[inline]
209 pub fn pull_threshold_for_queue(mut self, pull_threshold_for_queue: u32) -> Self {
210 self.pull_threshold_for_queue = Some(pull_threshold_for_queue);
211 self
212 }
213
214 #[inline]
215 pub fn pop_threshold_for_queue(mut self, pop_threshold_for_queue: u32) -> Self {
216 self.pop_threshold_for_queue = Some(pop_threshold_for_queue);
217 self
218 }
219
220 #[inline]
221 pub fn pull_threshold_size_for_queue(mut self, pull_threshold_size_for_queue: u32) -> Self {
222 self.pull_threshold_size_for_queue = Some(pull_threshold_size_for_queue);
223 self
224 }
225
226 #[inline]
227 pub fn pull_threshold_for_topic(mut self, pull_threshold_for_topic: i32) -> Self {
228 self.pull_threshold_for_topic = Some(pull_threshold_for_topic);
229 self
230 }
231
232 #[inline]
233 pub fn pull_threshold_size_for_topic(mut self, pull_threshold_size_for_topic: i32) -> Self {
234 self.pull_threshold_size_for_topic = Some(pull_threshold_size_for_topic);
235 self
236 }
237
238 #[inline]
239 pub fn pull_interval(mut self, pull_interval: u64) -> Self {
240 self.pull_interval = Some(pull_interval);
241 self
242 }
243
244 #[inline]
245 pub fn consume_message_batch_max_size(mut self, consume_message_batch_max_size: u32) -> Self {
246 self.consume_message_batch_max_size = Some(consume_message_batch_max_size);
247 self
248 }
249
250 #[inline]
251 pub fn pull_batch_size(mut self, pull_batch_size: u32) -> Self {
252 self.pull_batch_size = Some(pull_batch_size);
253 self
254 }
255
256 #[inline]
257 pub fn pull_batch_size_in_bytes(mut self, pull_batch_size_in_bytes: u32) -> Self {
258 self.pull_batch_size_in_bytes = Some(pull_batch_size_in_bytes);
259 self
260 }
261
262 #[inline]
263 pub fn post_subscription_when_pull(mut self, post_subscription_when_pull: bool) -> Self {
264 self.post_subscription_when_pull = Some(post_subscription_when_pull);
265 self
266 }
267
268 #[inline]
269 pub fn unit_mode(mut self, unit_mode: bool) -> Self {
270 self.unit_mode = Some(unit_mode);
271 self
272 }
273
274 #[inline]
275 pub fn max_reconsume_times(mut self, max_reconsume_times: i32) -> Self {
276 self.max_reconsume_times = Some(max_reconsume_times);
277 self
278 }
279
280 #[inline]
281 pub fn suspend_current_queue_time_millis(mut self, suspend_current_queue_time_millis: u64) -> Self {
282 self.suspend_current_queue_time_millis = Some(suspend_current_queue_time_millis);
283 self
284 }
285
286 #[inline]
287 pub fn consume_timeout(mut self, consume_timeout: u64) -> Self {
288 self.consume_timeout = Some(consume_timeout);
289 self
290 }
291
292 #[inline]
293 pub fn pop_invisible_time(mut self, pop_invisible_time: u64) -> Self {
294 self.pop_invisible_time = Some(pop_invisible_time);
295 self
296 }
297
298 #[inline]
299 pub fn pop_batch_nums(mut self, pop_batch_nums: u32) -> Self {
300 self.pop_batch_nums = Some(pop_batch_nums);
301 self
302 }
303
304 #[inline]
305 pub fn await_termination_millis_when_shutdown(mut self, await_termination_millis_when_shutdown: u64) -> Self {
306 self.await_termination_millis_when_shutdown = Some(await_termination_millis_when_shutdown);
307 self
308 }
309
310 #[inline]
311 pub fn trace_dispatcher(mut self, trace_dispatcher: Option<ArcTraceDispatcher>) -> Self {
312 self.trace_dispatcher = trace_dispatcher;
313 self
314 }
315
316 #[inline]
317 pub fn client_rebalance(mut self, client_rebalance: bool) -> Self {
318 self.client_rebalance = Some(client_rebalance);
319 self
320 }
321
322 #[inline]
323 pub fn rpc_hook(mut self, rpc_hook: Option<Arc<dyn RPCHook>>) -> Self {
324 self.rpc_hook = rpc_hook;
325 self
326 }
327
328 #[inline]
329 pub fn tuning_profile(mut self, tuning_profile: ConsumerTuningProfile) -> Self {
330 self.tuning_profile = Some(tuning_profile);
331 self
332 }
333
334 pub fn build(mut self) -> DefaultMQPushConsumer {
336 let mut consumer_config = ConsumerConfig::default();
337 if let Some(profile) = self.tuning_profile {
338 consumer_config.apply_tuning_profile(profile);
339 }
340
341 if let Some(value) = self.consumer_group {
343 consumer_config.consumer_group = value;
344 }
345 if let Some(value) = self.message_model {
346 consumer_config.message_model = value;
347 }
348 if let Some(value) = self.consume_from_where {
349 consumer_config.consume_from_where = value;
350 }
351 if let Some(value) = self.consume_timestamp {
352 consumer_config.consume_timestamp = Some(value);
353 }
354 if let Some(value) = self.allocate_message_queue_strategy.take() {
355 consumer_config.allocate_message_queue_strategy = Some(value);
356 }
357 if let Some(value) = self.subscription {
358 consumer_config.subscription = value;
359 }
360 consumer_config.message_queue_listener = self.message_queue_listener.take();
361
362 if let Some(value) = self.consume_thread_min {
364 consumer_config.consume_thread_min = value;
365 }
366 if let Some(value) = self.consume_thread_max {
367 consumer_config.consume_thread_max = value;
368 }
369 if let Some(value) = self.adjust_thread_pool_nums_threshold {
370 consumer_config.adjust_thread_pool_nums_threshold = value;
371 }
372
373 if let Some(value) = self.consume_concurrently_max_span {
375 consumer_config.consume_concurrently_max_span = value;
376 }
377 if let Some(value) = self.pull_threshold_for_queue {
378 consumer_config.pull_threshold_for_queue = value;
379 }
380 if let Some(value) = self.pop_threshold_for_queue {
381 consumer_config.pop_threshold_for_queue = value;
382 }
383 if let Some(value) = self.pull_threshold_size_for_queue {
384 consumer_config.pull_threshold_size_for_queue = value;
385 }
386 if let Some(value) = self.pull_threshold_for_topic {
387 consumer_config.pull_threshold_for_topic = value;
388 }
389 if let Some(value) = self.pull_threshold_size_for_topic {
390 consumer_config.pull_threshold_size_for_topic = value;
391 }
392 if let Some(value) = self.pull_interval {
393 consumer_config.pull_interval = value;
394 }
395
396 if let Some(value) = self.consume_message_batch_max_size {
398 consumer_config.consume_message_batch_max_size = value;
399 }
400 if let Some(value) = self.pull_batch_size {
401 consumer_config.pull_batch_size = value;
402 }
403 if let Some(value) = self.pull_batch_size_in_bytes {
404 consumer_config.pull_batch_size_in_bytes = value;
405 }
406
407 if let Some(value) = self.post_subscription_when_pull {
409 consumer_config.post_subscription_when_pull = value;
410 }
411 if let Some(value) = self.unit_mode {
412 consumer_config.unit_mode = value;
413 }
414 if let Some(value) = self.max_reconsume_times {
415 consumer_config.max_reconsume_times = value;
416 }
417 if let Some(value) = self.suspend_current_queue_time_millis {
418 consumer_config.suspend_current_queue_time_millis = value;
419 }
420 if let Some(value) = self.consume_timeout {
421 consumer_config.consume_timeout = value;
422 }
423 if let Some(value) = self.pop_invisible_time {
424 consumer_config.pop_invisible_time = value;
425 }
426 if let Some(value) = self.pop_batch_nums {
427 consumer_config.pop_batch_nums = value;
428 }
429 if let Some(value) = self.await_termination_millis_when_shutdown {
430 consumer_config.await_termination_millis_when_shutdown = value;
431 }
432
433 consumer_config.trace_dispatcher = self.trace_dispatcher.clone();
435 if let Some(value) = self.client_rebalance {
436 consumer_config.client_rebalance = value;
437 }
438 consumer_config.rpc_hook = self.rpc_hook.clone();
439
440 DefaultMQPushConsumer::new_with_options(
441 self.client_runtime,
442 ClientOptions::from_parts(self.client_config, self.nameserver_discovery),
443 consumer_config,
444 )
445 }
446}
447
448#[cfg(test)]
449mod tests {
450 use super::*;
451 use crate::consumer::default_mq_push_consumer::ConsumerTuningProfile;
452
453 #[test]
454 fn tuning_profile_applies_before_explicit_builder_overrides() {
455 let consumer =
456 DefaultMQPushConsumerBuilder::new(crate::runtime::test_client_runtime("push-consumer-builder-test"))
457 .consumer_group("push_profile_builder_group")
458 .tuning_profile(ConsumerTuningProfile::Throughput)
459 .pull_batch_size(64)
460 .pull_batch_size_in_bytes(768 * 1024)
461 .build();
462
463 assert_eq!(consumer.consume_message_batch_max_size(), 16);
464 assert_eq!(consumer.pull_batch_size(), 64);
465 assert_eq!(consumer.pull_batch_size_in_bytes(), 768 * 1024);
466 assert_eq!(consumer.pull_threshold_for_queue(), 4096);
467 assert_eq!(consumer.pull_threshold_size_for_queue(), 256);
468 }
469}