1pub mod memory;
8
9#[cfg(feature = "rabbitmq")]
10pub mod rabbitmq;
11#[cfg(feature = "redis")]
12pub mod redis;
13
14use crate::config::QueueKind;
15use crate::{RagConfig, RagError, Result};
16use async_trait::async_trait;
17use std::sync::Arc;
18
19pub const TOPIC: &str = "docling_rag_ingest";
21
22#[async_trait]
24pub trait QueueReceiver: Send {
25 async fn recv(&mut self) -> Option<Vec<u8>>;
27}
28
29#[async_trait]
31pub trait MessageQueue: Send + Sync {
32 async fn publish(&self, payload: &[u8]) -> Result<()>;
34
35 async fn subscribe(&self) -> Result<Box<dyn QueueReceiver>>;
37}
38
39pub async fn from_config(cfg: &RagConfig) -> Result<Arc<dyn MessageQueue>> {
41 match cfg.queue {
42 QueueKind::Memory => Ok(Arc::new(memory::MemoryQueue::new())),
43 QueueKind::RabbitMq => {
44 #[cfg(feature = "rabbitmq")]
45 {
46 let url = cfg.rabbitmq_url.clone().ok_or_else(|| {
47 RagError::config("RABBITMQ_URL is required for the rabbitmq queue")
48 })?;
49 Ok(Arc::new(rabbitmq::RabbitMqQueue::connect(&url).await?))
50 }
51 #[cfg(not(feature = "rabbitmq"))]
52 {
53 Err(RagError::FeatureDisabled(
54 "rabbitmq".into(),
55 "rabbitmq".into(),
56 ))
57 }
58 }
59 QueueKind::Redis => {
60 #[cfg(feature = "redis")]
61 {
62 let url = cfg
63 .redis_url
64 .clone()
65 .ok_or_else(|| RagError::config("REDIS_URL is required for the redis queue"))?;
66 Ok(Arc::new(redis::RedisQueue::connect(&url).await?))
67 }
68 #[cfg(not(feature = "redis"))]
69 {
70 Err(RagError::FeatureDisabled("redis".into(), "redis".into()))
71 }
72 }
73 }
74}