dmsc/queue/config.rs
1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of DMSC.
4//! The DMSC project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//! http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18#![allow(non_snake_case)]
19
20//! # Queue Configuration
21//!
22//! This file defines the configuration structures for the DMSC queue system. These structures
23//! provide a centralized way to configure queue behavior, including backend selection,
24//! connection settings, retry policies, and dead letter queue configuration.
25//!
26//! ## Key Components
27//!
28//! - **DMSCQueueConfig**: Main queue configuration structure
29//! - **QueueBackendType**: Enum for supported queue backends
30//! - **RetryPolicy**: Configuration for message retry behavior
31//! - **DeadLetterConfig**: Configuration for dead letter queue functionality
32//!
33//! ## Design Principles
34//!
35//! 1. **Default Values**: All configuration structures have sensible default values
36//! 2. **Serialization Support**: All structures are serializable/deserializable for config file support
37//! 3. **Type Safety**: Strongly typed enums for backend selection
38//! 4. **Flexibility**: Supports multiple queue backends through a unified configuration
39//! 5. **Retry Mechanism**: Configurable retry policies with exponential backoff support
40//! 6. **Dead Letter Support**: Optional dead letter queue configuration for failed messages
41//! 7. **Backend Agnostic**: Configuration can be used with any queue backend
42//! 8. **Timeout Configuration**: Separate timeouts for producers and consumers
43//!
44//! ## Usage
45//!
46//! ```rust,ignore
47//! use dmsc::queue::{DMSCQueueConfig, QueueBackendType, RetryPolicy, DeadLetterConfig};
48//!
49//! // Create default queue configuration
50//! let default_config = DMSCQueueConfig::default();
51//!
52//! // Create custom queue configuration
53//! let custom_config = DMSCQueueConfig {
54//! enabled: true,
55//! backend_type: QueueBackendType::RabbitMQ,
56//! connection_string: "amqp://guest:guest@localhost:5672/".to_string(),
57//! max_connections: 20,
58//! message_max_size: 2 * 1024 * 1024, // 2MB
59//! consumer_timeout_ms: 60000, // 60 seconds
60//! producer_timeout_ms: 10000, // 10 seconds
61//! retry_policy: RetryPolicy {
62//! max_retries: 5,
63//! initial_delay_ms: 2000,
64//! max_delay_ms: 30000,
65//! backoff_multiplier: 1.5,
66//! },
67//! dead_letter_config: Some(DeadLetterConfig {
68//! enabled: true,
69//! max_retry_count: 3,
70//! dead_letter_queue_name: "dead_letters".to_string(),
71//! ttl_hours: 24,
72//! }),
73//! };
74//!
75//! // Parse backend type from string
76//! let backend_type = QueueBackendType::from_str("redis").unwrap();
77//! assert_eq!(backend_type, QueueBackendType::Redis);
78//! ```
79
80use serde::{Deserialize, Serialize};
81use std::str::FromStr;
82
83/// Main queue configuration structure.
84///
85/// This structure contains all the configuration options for the queue system, including
86/// backend selection, connection settings, timeouts, retry policies, and dead letter queue
87/// configuration.
88#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct DMSCQueueConfig {
91 /// Whether the queue system is enabled
92 pub enabled: bool,
93 /// The type of queue backend to use
94 pub backend_type: DMSCQueueBackendType,
95 /// Connection string for the queue backend
96 pub connection_string: String,
97 /// Maximum number of connections to the queue backend
98 pub max_connections: u32,
99 /// Maximum size of messages in bytes
100 pub message_max_size: usize,
101 /// Timeout for consumer operations in milliseconds
102 pub consumer_timeout_ms: u64,
103 /// Timeout for producer operations in milliseconds
104 pub producer_timeout_ms: u64,
105 /// Configuration for message retry behavior
106 pub retry_policy: DMSCRetryPolicy,
107 /// Configuration for dead letter queue functionality
108 pub dead_letter_config: Option<DMSCDeadLetterConfig>,
109}
110
111impl Default for DMSCQueueConfig {
112 /// Creates a new queue configuration with sensible default values.
113 ///
114 /// # Returns
115 ///
116 /// A `DMSCQueueConfig` instance with default values
117 fn default() -> Self {
118 Self {
119 enabled: true,
120 backend_type: DMSCQueueBackendType::Memory,
121 connection_string: "memory://localhost".to_string(),
122 max_connections: 10,
123 message_max_size: 1024 * 1024, // 1MB
124 consumer_timeout_ms: 30000, // 30 seconds
125 producer_timeout_ms: 5000, // 5 seconds
126 retry_policy: DMSCRetryPolicy::default(),
127 dead_letter_config: None,
128 }
129 }
130}
131
132/// Enum representing supported queue backend types.
133///
134/// This enum defines the different queue backends that can be used with the DMSC queue system.
135#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
136#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
137pub enum DMSCQueueBackendType {
138 /// In-memory queue implementation for testing and development
139 Memory,
140 /// RabbitMQ queue backend for production use
141 RabbitMQ,
142 /// Kafka queue backend for high-throughput scenarios
143 Kafka,
144 /// Redis queue backend for simple, lightweight queueing
145 Redis,
146}
147
148#[cfg(feature = "pyo3")]
149#[pyo3::prelude::pymethods]
150impl DMSCQueueBackendType {
151 #[staticmethod]
152 fn from_string(s: String) -> Self {
153 s.parse().unwrap_or(DMSCQueueBackendType::Memory)
154 }
155}
156
157impl FromStr for DMSCQueueBackendType {
158 type Err = String;
159
160 /// Parses a string into a QueueBackendType.
161 ///
162 /// # Parameters
163 ///
164 /// - `s`: The string to parse
165 ///
166 /// # Returns
167 ///
168 /// A `Result<Self, Self::Err>` containing the parsed backend type or an error
169 fn from_str(s: &str) -> Result<Self, Self::Err> {
170 match s.to_lowercase().as_str() {
171 "memory" => Ok(DMSCQueueBackendType::Memory),
172 "rabbitmq" => Ok(DMSCQueueBackendType::RabbitMQ),
173 "kafka" => Ok(DMSCQueueBackendType::Kafka),
174 "redis" => Ok(DMSCQueueBackendType::Redis),
175 _ => Err(format!("Unknown queue backend type: {s}")),
176 }
177 }
178}
179
180/// Configuration for message retry behavior.
181///
182/// This structure defines the retry policy for failed messages, including maximum retry
183/// attempts, initial delay, maximum delay, and backoff multiplier.
184#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct DMSCRetryPolicy {
187 /// Maximum number of retry attempts for a failed message
188 pub max_retries: u32,
189 /// Initial delay in milliseconds before the first retry
190 pub initial_delay_ms: u64,
191 /// Maximum delay in milliseconds between retries
192 pub max_delay_ms: u64,
193 /// Multiplier for exponential backoff (e.g., 2.0 for doubling delay each retry)
194 pub backoff_multiplier: f64,
195}
196
197impl Default for DMSCRetryPolicy {
198 /// Creates a new retry policy with sensible default values.
199 ///
200 /// # Returns
201 ///
202 /// A `DMSCRetryPolicy` instance with default values
203 fn default() -> Self {
204 Self {
205 max_retries: 3,
206 initial_delay_ms: 1000,
207 max_delay_ms: 60000,
208 backoff_multiplier: 2.0,
209 }
210 }
211}
212
213#[cfg(feature = "pyo3")]
214#[pyo3::prelude::pymethods]
215impl DMSCRetryPolicy {
216 #[new]
217 fn py_new() -> Self {
218 Self::default()
219 }
220
221 #[staticmethod]
222 fn py_new_with_values(max_retries: u32, initial_delay_ms: u64, max_delay_ms: u64, backoff_multiplier: f64) -> Self {
223 Self {
224 max_retries,
225 initial_delay_ms,
226 max_delay_ms,
227 backoff_multiplier,
228 }
229 }
230}
231
232/// Configuration for dead letter queue functionality.
233///
234/// This structure defines the configuration for dead letter queues, which are used to store
235/// messages that have failed to process after maximum retry attempts.
236#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
237#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct DMSCDeadLetterConfig {
239 /// Whether dead letter queue functionality is enabled
240 pub enabled: bool,
241 /// Maximum number of retry attempts before a message is sent to the dead letter queue
242 pub max_retry_count: u32,
243 /// Name of the dead letter queue
244 pub dead_letter_queue_name: String,
245 /// Time-to-live for messages in the dead letter queue in hours
246 pub ttl_hours: u32,
247}
248
249impl Default for DMSCDeadLetterConfig {
250 fn default() -> Self {
251 Self {
252 enabled: false,
253 max_retry_count: 3,
254 dead_letter_queue_name: "dead_letter".to_string(),
255 ttl_hours: 24,
256 }
257 }
258}
259
260#[cfg(feature = "pyo3")]
261#[pyo3::prelude::pymethods]
262impl DMSCDeadLetterConfig {
263 #[new]
264 fn py_new() -> Self {
265 Self::default()
266 }
267
268 #[staticmethod]
269 fn py_new_enabled(dead_letter_queue_name: String, ttl_hours: u32) -> Self {
270 Self {
271 enabled: true,
272 max_retry_count: 3,
273 dead_letter_queue_name,
274 ttl_hours,
275 }
276 }
277}
278
279#[cfg(feature = "pyo3")]
280/// Python bindings for DMSCQueueConfig
281#[pyo3::prelude::pymethods]
282impl DMSCQueueConfig {
283 #[new]
284 fn py_new() -> Self {
285 Self::default()
286 }
287
288 #[staticmethod]
289 fn py_new_with_memory_backend() -> Self {
290 Self {
291 enabled: true,
292 backend_type: DMSCQueueBackendType::Memory,
293 connection_string: "memory://localhost".to_string(),
294 ..Self::default()
295 }
296 }
297
298 #[staticmethod]
299 fn py_new_with_redis_backend(connection_string: String) -> Self {
300 Self {
301 enabled: true,
302 backend_type: DMSCQueueBackendType::Redis,
303 connection_string,
304 ..Self::default()
305 }
306 }
307}