rocketmq_client_rust/producer/send_callback.rs
1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Callback abstractions for asynchronous message send operations.
16//!
17//! This module provides the [`SendCallback`] trait and related types for handling
18//! results of asynchronous message send operations. Callbacks can be implemented
19//! directly as trait implementations or provided as closures through automatic
20//! blanket implementation.
21
22use std::sync::Arc;
23
24use crate::ClientError;
25
26use crate::producer::send_result::SendResult;
27
28/// Callback trait for handling asynchronous message send results.
29///
30/// Implementors of this trait can respond to successful message delivery or
31/// send failures. Closures that match the expected signature automatically
32/// implement this trait through blanket implementation.
33///
34/// # Examples
35///
36/// Using a closure as callback:
37///
38/// ```rust,ignore
39/// producer.send_with_callback(message, |result, error| {
40/// match (result, error) {
41/// (Some(send_result), None) => {
42/// println!("Sent: {:?}", send_result.msg_id);
43/// }
44/// (None, Some(err)) => {
45/// eprintln!("Failed: {}", err);
46/// }
47/// _ => {}
48/// }
49/// }).await?;
50/// ```
51///
52/// Implementing the trait:
53///
54/// ```rust,ignore
55/// struct LoggingCallback;
56///
57/// impl SendCallback for LoggingCallback {
58/// fn on_success(&self, send_result: &SendResult) {
59/// log::info!("Message sent: {:?}", send_result.msg_id);
60/// }
61///
62/// fn on_exception(&self, error: &ClientError) {
63/// log::error!("Send failed: {}", error);
64/// }
65/// }
66/// ```
67pub trait SendCallback: Send + Sync {
68 /// Invoked when a message is successfully sent.
69 ///
70 /// # Arguments
71 ///
72 /// * `send_result` - Contains the message ID, queue information, and send metadata.
73 fn on_success(&self, send_result: &SendResult);
74
75 /// Invoked when a message send operation fails.
76 ///
77 /// # Arguments
78 ///
79 /// * `error` - The error that caused the send failure.
80 fn on_exception(&self, error: &ClientError);
81}
82
83// Blanket implementation allowing closures to act as callbacks.
84//
85// Closures receive `Option<&SendResult>` and `Option<&ClientError>` parameters,
86// where exactly one is `Some` and the other is `None`.
87impl<F> SendCallback for F
88where
89 F: Fn(Option<&SendResult>, Option<&ClientError>) + Send + Sync,
90{
91 fn on_success(&self, send_result: &SendResult) {
92 self(Some(send_result), None)
93 }
94
95 fn on_exception(&self, error: &ClientError) {
96 self(None, Some(error))
97 }
98}
99
100/// Type alias for dynamically dispatched send callbacks.
101///
102/// Use this type when storing callbacks in struct fields or when the callback
103/// type cannot be determined at compile time. For function parameters, prefer
104/// generic bounds over `SendCallback` to enable monomorphization.
105///
106/// # Examples
107///
108/// ```rust,ignore
109/// struct ProducerState {
110/// pending: Vec<ArcSendCallback>,
111/// }
112///
113/// impl ProducerState {
114/// fn add<CB: SendCallback + 'static>(&mut self, callback: CB) {
115/// self.pending.push(Arc::new(callback));
116/// }
117/// }
118/// ```
119pub type ArcSendCallback = Arc<dyn SendCallback>;
120
121/// Legacy type alias for backward compatibility.
122///
123/// This type is deprecated in favor of the trait-based approach.
124/// Use `ArcSendCallback` for storage or generic `SendCallback` bound for parameters.
125///
126/// # Migration
127///
128/// ```rust,ignore
129/// // Old style (still works)
130/// let callback: SendMessageCallback = Arc::new(|result, error| { /* ... */ });
131///
132/// // New style (recommended)
133/// let callback: ArcSendCallback = Arc::new(|result, error| { /* ... */ });
134///
135/// // Or use generic parameter (best performance)
136/// fn my_function<CB: SendCallback + 'static>(callback: CB) { /* ... */ }
137/// ```
138#[deprecated(since = "0.8.0", note = "Use ArcSendCallback or generic SendCallback bound instead")]
139pub type SendMessageCallback = Arc<dyn Fn(Option<&SendResult>, Option<&ClientError>) + Send + Sync>;