rocketmq_client_rust/consumer/
default_mq_pull_consumer.rs1#![allow(deprecated)]
16
17use std::sync::Arc;
18use std::time::Duration;
19
20use crate::ClientError;
21use crate::ClientResult;
22use cheetah_string::CheetahString;
23use rocketmq_model::common::message::message_queue::MessageQueue;
24
25use crate::base::client_config::ClientConfig;
26use crate::consumer::consumer_impl::default_mq_pull_consumer_impl::DefaultMQPullConsumerImpl;
27use crate::consumer::default_lite_pull_consumer::DefaultLitePullConsumer;
28use crate::consumer::default_mq_pull_consumer_builder::DefaultMQPullConsumerBuilder;
29use crate::consumer::message_queue_listener::MessageQueueListener;
30use crate::consumer::message_selector::MessageSelector;
31use crate::consumer::pull_result::PullResult;
32use crate::runtime::ClientRuntime;
33
34#[derive(Debug, Clone)]
36pub struct PullOptions {
37 message_queue: MessageQueue,
38 selector: MessageSelector,
39 offset: i64,
40 max_messages: i32,
41 max_size_in_bytes: i32,
42 timeout: Duration,
43 broker_suspend_timeout: Duration,
44 block_if_not_found: bool,
45}
46
47impl PullOptions {
48 pub fn new(
55 message_queue: MessageQueue,
56 selector: MessageSelector,
57 offset: i64,
58 max_messages: i32,
59 ) -> ClientResult<Self> {
60 let options = Self {
61 message_queue,
62 selector,
63 offset,
64 max_messages,
65 max_size_in_bytes: i32::MAX,
66 timeout: Duration::from_secs(10),
67 broker_suspend_timeout: Duration::from_secs(20),
68 block_if_not_found: false,
69 };
70 options.validate()?;
71 Ok(options)
72 }
73
74 pub fn max_size_in_bytes(mut self, max_size_in_bytes: i32) -> Self {
76 self.max_size_in_bytes = max_size_in_bytes;
77 self
78 }
79
80 pub fn timeout(mut self, timeout: Duration) -> Self {
82 self.timeout = timeout;
83 self
84 }
85
86 pub fn broker_suspend_timeout(mut self, timeout: Duration) -> Self {
88 self.broker_suspend_timeout = timeout;
89 self
90 }
91
92 pub fn block_if_not_found(mut self, block_if_not_found: bool) -> Self {
94 self.block_if_not_found = block_if_not_found;
95 self
96 }
97
98 pub fn validate(&self) -> ClientResult<()> {
105 if self.message_queue.topic().is_empty() {
106 return Err(crate::mq_client_err!("message queue topic is empty"));
107 }
108 if self.message_queue.broker_name().is_empty() {
109 return Err(crate::mq_client_err!("message queue broker name is empty"));
110 }
111 if self.offset < 0 {
112 return Err(crate::mq_client_err!("offset < 0"));
113 }
114 if self.max_messages <= 0 {
115 return Err(crate::mq_client_err!("maxNums <= 0"));
116 }
117 if self.max_size_in_bytes <= 0 {
118 return Err(crate::mq_client_err!("maxSizeInBytes <= 0"));
119 }
120 if self.timeout.is_zero() {
121 return Err(crate::mq_client_err!("pull timeout must be positive"));
122 }
123 if self.broker_suspend_timeout.is_zero() {
124 return Err(crate::mq_client_err!("broker suspend timeout must be positive"));
125 }
126 if self.block_if_not_found && self.timeout <= self.broker_suspend_timeout {
127 return Err(crate::mq_client_err!(
128 "block-if-not-found timeout must exceed broker suspend timeout"
129 ));
130 }
131 Ok(())
132 }
133
134 pub fn message_queue(&self) -> &MessageQueue {
136 &self.message_queue
137 }
138
139 pub fn selector(&self) -> &MessageSelector {
141 &self.selector
142 }
143
144 pub fn offset(&self) -> i64 {
146 self.offset
147 }
148
149 pub fn max_messages(&self) -> i32 {
151 self.max_messages
152 }
153
154 pub fn max_size_in_bytes_value(&self) -> i32 {
156 self.max_size_in_bytes
157 }
158
159 pub fn timeout_value(&self) -> Duration {
161 self.timeout
162 }
163
164 pub fn broker_suspend_timeout_value(&self) -> Duration {
166 self.broker_suspend_timeout
167 }
168
169 pub fn is_block_if_not_found(&self) -> bool {
171 self.block_if_not_found
172 }
173
174 pub(crate) fn with_message_queue(mut self, message_queue: MessageQueue) -> Self {
175 self.message_queue = message_queue;
176 self
177 }
178}
179
180pub trait ClassicPullCallback: Send + Sync + 'static {
182 fn on_success(&self, pull_result: PullResult);
184
185 fn on_exception(&self, error: ClientError);
187}
188
189impl<F> ClassicPullCallback for F
191where
192 F: Fn(Result<PullResult, ClientError>) + Send + Sync + 'static,
193{
194 fn on_success(&self, pull_result: PullResult) {
195 self(Ok(pull_result));
196 }
197
198 fn on_exception(&self, error: ClientError) {
199 self(Err(error));
200 }
201}
202
203#[deprecated(
205 since = "0.9.0",
206 note = "Classic Pull is retained for compatibility; prefer DefaultLitePullConsumer for new applications"
207)]
208#[derive(Clone, Default)]
209pub struct DefaultMQPullConsumer {
210 consumer_group: Option<CheetahString>,
211 implementation: Option<DefaultMQPullConsumerImpl>,
212}
213
214#[allow(deprecated)]
215impl DefaultMQPullConsumer {
216 pub fn new() -> Self {
221 Self::default()
222 }
223
224 pub fn with_consumer_group(consumer_group: impl Into<CheetahString>) -> Self {
226 Self {
227 consumer_group: Some(consumer_group.into()),
228 implementation: None,
229 }
230 }
231
232 pub fn builder(client_runtime: Arc<ClientRuntime>) -> DefaultMQPullConsumerBuilder {
234 DefaultMQPullConsumerBuilder::new(client_runtime)
235 }
236
237 pub(crate) fn from_lite_consumer(
238 consumer_group: CheetahString,
239 lite_consumer: DefaultLitePullConsumer,
240 consumer_pull_timeout: Duration,
241 broker_suspend_timeout: Duration,
242 consumer_timeout_when_suspend: Duration,
243 ) -> ClientResult<Self> {
244 Ok(Self {
245 consumer_group: Some(consumer_group),
246 implementation: Some(DefaultMQPullConsumerImpl::from_lite_consumer(
247 lite_consumer,
248 consumer_pull_timeout,
249 broker_suspend_timeout,
250 consumer_timeout_when_suspend,
251 )?),
252 })
253 }
254
255 fn implementation(&self) -> ClientResult<&DefaultMQPullConsumerImpl> {
256 self.implementation.as_ref().ok_or_else(|| {
257 ClientError::not_initialized(
258 "DefaultMQPullConsumer has no ClientRuntime; create it with DefaultMQPullConsumer::builder",
259 )
260 })
261 }
262
263 pub fn consumer_group(&self) -> Option<&CheetahString> {
265 self.consumer_group.as_ref()
266 }
267
268 pub fn client_config(&self) -> ClientResult<Arc<ClientConfig>> {
274 self.implementation()?.client_config()
275 }
276
277 pub async fn start(&self) -> ClientResult<()> {
284 self.implementation()?.start().await
285 }
286
287 pub async fn shutdown(&self) -> ClientResult<()> {
294 self.implementation()?.shutdown().await
295 }
296
297 pub async fn is_running(&self) -> bool {
299 match &self.implementation {
300 Some(implementation) => implementation.is_running().await,
301 None => false,
302 }
303 }
304
305 pub async fn pull(
312 &self,
313 message_queue: &MessageQueue,
314 sub_expression: &str,
315 offset: i64,
316 max_messages: i32,
317 ) -> ClientResult<PullResult> {
318 let implementation = self.implementation()?;
319 let options = PullOptions::new(
320 message_queue.clone(),
321 MessageSelector::by_tag(sub_expression),
322 offset,
323 max_messages,
324 )?
325 .timeout(implementation.consumer_pull_timeout())
326 .broker_suspend_timeout(implementation.broker_suspend_timeout());
327 implementation.pull_with_options(options).await
328 }
329
330 pub async fn pull_with_selector(
337 &self,
338 message_queue: &MessageQueue,
339 selector: MessageSelector,
340 offset: i64,
341 max_messages: i32,
342 ) -> ClientResult<PullResult> {
343 let implementation = self.implementation()?;
344 implementation
345 .pull_with_options(
346 PullOptions::new(message_queue.clone(), selector, offset, max_messages)?
347 .timeout(implementation.consumer_pull_timeout())
348 .broker_suspend_timeout(implementation.broker_suspend_timeout()),
349 )
350 .await
351 }
352
353 pub async fn pull_async<C>(
360 &self,
361 message_queue: &MessageQueue,
362 sub_expression: &str,
363 offset: i64,
364 max_messages: i32,
365 callback: C,
366 ) -> ClientResult<()>
367 where
368 C: ClassicPullCallback,
369 {
370 let implementation = self.implementation()?;
371 let options = PullOptions::new(
372 message_queue.clone(),
373 MessageSelector::by_tag(sub_expression),
374 offset,
375 max_messages,
376 )?
377 .timeout(implementation.consumer_pull_timeout())
378 .broker_suspend_timeout(implementation.broker_suspend_timeout());
379 implementation.pull_async_with_options(options, callback).await
380 }
381
382 pub async fn pull_async_with_selector<C>(
389 &self,
390 message_queue: &MessageQueue,
391 selector: MessageSelector,
392 offset: i64,
393 max_messages: i32,
394 callback: C,
395 ) -> ClientResult<()>
396 where
397 C: ClassicPullCallback,
398 {
399 let implementation = self.implementation()?;
400 let options = PullOptions::new(message_queue.clone(), selector, offset, max_messages)?
401 .timeout(implementation.consumer_pull_timeout())
402 .broker_suspend_timeout(implementation.broker_suspend_timeout());
403 implementation.pull_async_with_options(options, callback).await
404 }
405
406 pub async fn pull_with_options(&self, options: PullOptions) -> ClientResult<PullResult> {
412 self.implementation()?.pull_with_options(options).await
413 }
414
415 pub async fn pull_block_if_not_found(
421 &self,
422 message_queue: &MessageQueue,
423 sub_expression: &str,
424 offset: i64,
425 max_messages: i32,
426 ) -> ClientResult<PullResult> {
427 let implementation = self.implementation()?;
428 let options = PullOptions::new(
429 message_queue.clone(),
430 MessageSelector::by_tag(sub_expression),
431 offset,
432 max_messages,
433 )?
434 .timeout(implementation.consumer_timeout_when_suspend())
435 .broker_suspend_timeout(implementation.broker_suspend_timeout())
436 .block_if_not_found(true);
437 implementation.pull_with_options(options).await
438 }
439
440 pub async fn pull_async_with_options<C>(&self, options: PullOptions, callback: C) -> ClientResult<()>
447 where
448 C: ClassicPullCallback,
449 {
450 self.implementation()?.pull_async_with_options(options, callback).await
451 }
452
453 pub async fn pull_block_if_not_found_async<C>(
460 &self,
461 message_queue: &MessageQueue,
462 sub_expression: &str,
463 offset: i64,
464 max_messages: i32,
465 callback: C,
466 ) -> ClientResult<()>
467 where
468 C: ClassicPullCallback,
469 {
470 let implementation = self.implementation()?;
471 let options = PullOptions::new(
472 message_queue.clone(),
473 MessageSelector::by_tag(sub_expression),
474 offset,
475 max_messages,
476 )?
477 .timeout(implementation.consumer_timeout_when_suspend())
478 .broker_suspend_timeout(implementation.broker_suspend_timeout())
479 .block_if_not_found(true);
480 implementation.pull_async_with_options(options, callback).await
481 }
482
483 pub async fn fetch_subscribe_message_queues(&self, topic: &str) -> ClientResult<Vec<MessageQueue>> {
489 self.implementation()?.fetch_subscribe_message_queues(topic).await
490 }
491
492 pub async fn register_message_queue_listener<L>(&self, topic: &str, listener: L) -> ClientResult<()>
499 where
500 L: MessageQueueListener + 'static,
501 {
502 self.implementation()?
503 .register_message_queue_listener(topic, Arc::new(listener))
504 .await
505 }
506
507 pub async fn update_consume_offset(&self, message_queue: &MessageQueue, offset: i64) -> ClientResult<()> {
514 self.implementation()?
515 .update_consume_offset(message_queue, offset)
516 .await
517 }
518
519 pub async fn fetch_consume_offset(&self, message_queue: &MessageQueue, from_store: bool) -> ClientResult<i64> {
526 self.implementation()?
527 .fetch_consume_offset(message_queue, from_store)
528 .await
529 }
530
531 pub async fn search_offset(&self, message_queue: &MessageQueue, timestamp: u64) -> ClientResult<i64> {
537 self.implementation()?.search_offset(message_queue, timestamp).await
538 }
539
540 pub async fn max_offset(&self, message_queue: &MessageQueue) -> ClientResult<i64> {
546 self.implementation()?.max_offset(message_queue).await
547 }
548
549 pub async fn min_offset(&self, message_queue: &MessageQueue) -> ClientResult<i64> {
555 self.implementation()?.min_offset(message_queue).await
556 }
557
558 pub fn default_mq_pull_consumer_impl(&self) -> ClientResult<DefaultMQPullConsumerImpl> {
564 self.implementation().cloned()
565 }
566}
567
568#[allow(async_fn_in_trait)]
570#[deprecated(
571 since = "0.9.0",
572 note = "Classic Pull is retained for compatibility; prefer DefaultLitePullConsumer for new applications"
573)]
574pub trait MQPullConsumer: Send + Sync {
575 async fn start(&self) -> ClientResult<()>;
577
578 async fn shutdown(&self) -> ClientResult<()>;
580
581 async fn pull(
583 &self,
584 message_queue: &MessageQueue,
585 sub_expression: &str,
586 offset: i64,
587 max_messages: i32,
588 ) -> ClientResult<PullResult>;
589}
590
591#[allow(deprecated)]
592impl MQPullConsumer for DefaultMQPullConsumer {
593 async fn start(&self) -> ClientResult<()> {
594 DefaultMQPullConsumer::start(self).await
595 }
596
597 async fn shutdown(&self) -> ClientResult<()> {
598 DefaultMQPullConsumer::shutdown(self).await
599 }
600
601 async fn pull(
602 &self,
603 message_queue: &MessageQueue,
604 sub_expression: &str,
605 offset: i64,
606 max_messages: i32,
607 ) -> ClientResult<PullResult> {
608 DefaultMQPullConsumer::pull(self, message_queue, sub_expression, offset, max_messages).await
609 }
610}