Skip to main content

flare_core/common/message/
pipeline.rs

1//! 消息处理管道
2//!
3//! 提供统一的消息处理流程,支持中间件、观察者、自动序列化/压缩
4
5use crate::common::MessageParser;
6use crate::common::error::{FlareError, Result};
7use crate::common::protocol::Frame;
8use crate::transport::events::ConnectionEvent;
9use async_trait::async_trait;
10use std::sync::Arc;
11use tokio::sync::RwLock;
12
13/// 消息处理上下文
14///
15/// 包含消息处理所需的所有上下文信息
16#[derive(Clone)]
17pub struct MessageContext {
18    /// 原始 Frame
19    pub frame: Frame,
20    /// 连接 ID(服务端)或 None(客户端)
21    pub connection_id: Option<String>,
22    /// 消息解析器(用于序列化/压缩)
23    pub parser: MessageParser,
24    /// 元数据(用于中间件传递数据)
25    pub metadata: Arc<RwLock<std::collections::HashMap<String, Vec<u8>>>>,
26}
27
28impl MessageContext {
29    /// 创建新的消息上下文
30    pub fn new(frame: Frame, connection_id: Option<String>, parser: MessageParser) -> Self {
31        Self {
32            frame,
33            connection_id,
34            parser,
35            metadata: Arc::new(RwLock::new(std::collections::HashMap::new())),
36        }
37    }
38
39    /// 设置元数据
40    pub async fn set_metadata(&self, key: String, value: Vec<u8>) {
41        let mut meta = self.metadata.write().await;
42        meta.insert(key, value);
43    }
44
45    /// 获取元数据
46    pub async fn get_metadata(&self, key: &str) -> Option<Vec<u8>> {
47        let meta = self.metadata.read().await;
48        meta.get(key).cloned()
49    }
50}
51
52/// 消息处理中间件
53///
54/// 支持在消息处理前后执行自定义逻辑
55#[async_trait]
56pub trait MessageMiddleware: Send + Sync {
57    /// 处理消息(在业务处理之前)
58    ///
59    /// # 参数
60    /// - `ctx`: 消息上下文
61    ///
62    /// # 返回
63    /// - `Ok(Some(Frame))`: 提前返回响应,不再继续处理
64    /// - `Ok(None)`: 继续处理
65    /// - `Err`: 处理失败,停止管道
66    async fn before(&self, ctx: &MessageContext) -> Result<Option<Frame>> {
67        let _ = ctx;
68        Ok(None)
69    }
70
71    /// 处理消息(在业务处理之后)
72    ///
73    /// # 参数
74    /// - `ctx`: 消息上下文
75    /// - `response`: 业务处理返回的响应(如果有)
76    ///
77    /// # 返回
78    /// - `Ok(Some(Frame))`: 修改后的响应
79    /// - `Ok(None)`: 使用原始响应
80    /// - `Err`: 处理失败
81    async fn after(&self, ctx: &MessageContext, response: Option<Frame>) -> Result<Option<Frame>> {
82        let _ = (ctx, response);
83        Ok(None)
84    }
85
86    /// 中间件名称(用于调试和日志)
87    fn name(&self) -> &str {
88        "UnknownMiddleware"
89    }
90
91    /// 中间件优先级(数字越小优先级越高)
92    fn priority(&self) -> u32 {
93        100
94    }
95}
96
97/// 线程安全的中间件引用
98pub type ArcMessageMiddleware = Arc<dyn MessageMiddleware>;
99
100/// 消息处理器
101///
102/// 处理具体的业务逻辑
103#[async_trait]
104pub trait MessageProcessor: Send + Sync {
105    /// 处理消息
106    ///
107    /// # 参数
108    /// - `ctx`: 消息上下文
109    ///
110    /// # 返回
111    /// - `Ok(Some(Frame))`: 需要发送的响应
112    /// - `Ok(None)`: 不需要响应
113    /// - `Err`: 处理失败
114    async fn process(&self, ctx: &MessageContext) -> Result<Option<Frame>>;
115
116    /// 处理器名称
117    fn name(&self) -> &str {
118        "UnknownProcessor"
119    }
120}
121
122/// 线程安全的处理器引用
123pub type ArcMessageProcessor = Arc<dyn MessageProcessor>;
124
125/// 消息处理管道
126///
127/// 统一的消息处理流程:
128/// 1. 原始数据 → 解析(自动解压、反序列化)→ Frame
129/// 2. Frame → 中间件(before)→ 处理器 → 中间件(after)→ 响应 Frame
130/// 3. 响应 Frame → 序列化(压缩、序列化)→ 原始数据
131#[derive(Clone)]
132pub struct MessagePipeline {
133    /// 中间件列表(按优先级排序)
134    middlewares: Arc<RwLock<Arc<Vec<ArcMessageMiddleware>>>>,
135    /// 处理器列表
136    processors: Arc<RwLock<Arc<Vec<ArcMessageProcessor>>>>,
137    /// 消息解析器(使用 Arc 以便在运行时更新)
138    parser: Arc<tokio::sync::Mutex<MessageParser>>,
139}
140
141impl MessagePipeline {
142    /// 创建新的消息处理管道
143    pub fn new(parser: MessageParser) -> Self {
144        Self {
145            middlewares: Arc::new(RwLock::new(Arc::new(Vec::new()))),
146            processors: Arc::new(RwLock::new(Arc::new(Vec::new()))),
147            parser: Arc::new(tokio::sync::Mutex::new(parser)),
148        }
149    }
150
151    /// 更新消息解析器(协商完成后调用)
152    pub async fn update_parser(&self, parser: MessageParser) {
153        let mut p = self.parser.lock().await;
154        *p = parser;
155    }
156
157    /// 添加中间件
158    pub async fn add_middleware(&self, middleware: ArcMessageMiddleware) {
159        let mut middlewares = self.middlewares.write().await;
160        let mut next = (**middlewares).clone();
161        next.push(middleware);
162        // 按优先级排序
163        next.sort_by_key(|m| m.priority());
164        *middlewares = Arc::new(next);
165    }
166
167    /// 移除中间件
168    pub async fn remove_middleware(&self, middleware: &ArcMessageMiddleware) {
169        let mut middlewares = self.middlewares.write().await;
170        let mut next = (**middlewares).clone();
171        next.retain(|m| !Arc::ptr_eq(m, middleware));
172        *middlewares = Arc::new(next);
173    }
174
175    /// 添加处理器
176    pub async fn add_processor(&self, processor: ArcMessageProcessor) {
177        let mut processors = self.processors.write().await;
178        let mut next = (**processors).clone();
179        next.push(processor);
180        *processors = Arc::new(next);
181    }
182
183    /// 移除处理器
184    pub async fn remove_processor(&self, processor: &ArcMessageProcessor) {
185        let mut processors = self.processors.write().await;
186        let mut next = (**processors).clone();
187        next.retain(|p| !Arc::ptr_eq(p, processor));
188        *processors = Arc::new(next);
189    }
190
191    /// 处理原始数据(自动解析)
192    ///
193    /// # 参数
194    /// - `data`: 原始字节数据
195    /// - `connection_id`: 连接 ID(服务端)或 None(客户端)
196    ///
197    /// # 返回
198    /// - `Ok(Some(Vec<u8>))`: 需要发送的响应数据
199    /// - `Ok(None)`: 不需要响应
200    /// - `Err`: 处理失败
201    pub async fn process_raw(
202        &self,
203        data: &[u8],
204        connection_id: Option<&str>,
205    ) -> Result<Option<Vec<u8>>> {
206        // 1. 解析消息(自动解压、反序列化)
207        let parser = self.parser.lock().await;
208        let frame = parser.parse(data).map_err(|e| {
209            FlareError::deserialization_error(format!("Failed to parse message: {}", e))
210        })?;
211        let parser_snapshot = parser.clone();
212        drop(parser);
213
214        // 2. 处理 Frame
215        let response = self
216            .process_frame_with_parser(&frame, connection_id, parser_snapshot.clone())
217            .await?;
218
219        // 3. 序列化响应(如果有)
220        if let Some(response_frame) = response {
221            let response_data = parser_snapshot.serialize(&response_frame).map_err(|e| {
222                FlareError::encoding_error(format!("Failed to serialize response: {}", e))
223            })?;
224            Ok(Some(response_data))
225        } else {
226            Ok(None)
227        }
228    }
229
230    async fn middleware_snapshot(&self) -> Arc<Vec<ArcMessageMiddleware>> {
231        let middlewares = self.middlewares.read().await;
232        Arc::clone(&middlewares)
233    }
234
235    async fn processor_snapshot(&self) -> Arc<Vec<ArcMessageProcessor>> {
236        let processors = self.processors.read().await;
237        Arc::clone(&processors)
238    }
239
240    /// 处理 Frame
241    ///
242    /// # 参数
243    /// - `frame`: 消息 Frame
244    /// - `connection_id`: 连接 ID(服务端)或 None(客户端)
245    ///
246    /// # 返回
247    /// - `Ok(Some(Frame))`: 需要发送的响应 Frame
248    /// - `Ok(None)`: 不需要响应
249    /// - `Err`: 处理失败
250    pub async fn process_frame(
251        &self,
252        frame: &Frame,
253        connection_id: Option<&str>,
254    ) -> Result<Option<Frame>> {
255        let parser = self.parser.lock().await;
256        let parser_snapshot = parser.clone();
257        drop(parser);
258
259        self.process_frame_with_parser(frame, connection_id, parser_snapshot)
260            .await
261    }
262
263    async fn process_frame_with_parser(
264        &self,
265        frame: &Frame,
266        connection_id: Option<&str>,
267        parser: MessageParser,
268    ) -> Result<Option<Frame>> {
269        // 创建消息上下文
270        let ctx = MessageContext::new(frame.clone(), connection_id.map(|s| s.to_string()), parser);
271
272        // 1. 执行中间件(before)
273        let middlewares = self.middleware_snapshot().await;
274        for middleware in middlewares.iter() {
275            if let Some(response) = middleware.before(&ctx).await? {
276                // 中间件提前返回响应
277                return Ok(Some(response));
278            }
279        }
280
281        // 2. 执行处理器
282        let processors = self.processor_snapshot().await;
283        let mut response = None;
284        for processor in processors.iter() {
285            if let Some(resp) = processor.process(&ctx).await? {
286                response = Some(resp);
287                break; // 第一个返回响应的处理器生效
288            }
289        }
290
291        // 3. 执行中间件(after)
292        let middlewares = self.middleware_snapshot().await;
293        for middleware in middlewares.iter() {
294            if let Some(modified_response) = middleware.after(&ctx, response.clone()).await? {
295                response = Some(modified_response);
296            }
297        }
298
299        Ok(response)
300    }
301
302    /// 处理连接事件
303    ///
304    /// # 参数
305    /// - `event`: 连接事件
306    /// - `connection_id`: 连接 ID(服务端)或 None(客户端)
307    pub async fn handle_connection_event(
308        &self,
309        _event: &ConnectionEvent,
310        _connection_id: Option<&str>,
311    ) -> Result<()> {
312        // 连接事件可以传递给中间件处理
313        let middlewares = self.middleware_snapshot().await;
314        for _middleware in middlewares.iter() {
315            // 如果中间件实现了连接事件处理,可以在这里调用
316            // 目前先跳过,后续可以扩展
317        }
318        Ok(())
319    }
320}
321
322impl Default for MessagePipeline {
323    fn default() -> Self {
324        Self::new(MessageParser::protobuf())
325    }
326}
327
328#[cfg(test)]
329mod tests {
330    use super::*;
331    use crate::common::protocol::{
332        Command, FrameBuilder, Reliability, SerializationFormat, frame_with_system_command, ping,
333        pong,
334    };
335    use tokio::sync::{Mutex, oneshot};
336
337    struct BlockingMiddleware {
338        entered_tx: Mutex<Option<oneshot::Sender<()>>>,
339        release_rx: Mutex<Option<oneshot::Receiver<()>>>,
340    }
341
342    #[async_trait]
343    impl MessageMiddleware for BlockingMiddleware {
344        async fn before(&self, _ctx: &MessageContext) -> Result<Option<Frame>> {
345            if let Some(tx) = self.entered_tx.lock().await.take() {
346                let _ = tx.send(());
347            }
348            if let Some(rx) = self.release_rx.lock().await.take() {
349                let _ = rx.await;
350            }
351            Ok(None)
352        }
353    }
354
355    struct NoopMiddleware;
356
357    #[async_trait]
358    impl MessageMiddleware for NoopMiddleware {}
359
360    struct ParserUpdatingProcessor {
361        pipeline: MessagePipeline,
362    }
363
364    #[async_trait]
365    impl MessageProcessor for ParserUpdatingProcessor {
366        async fn process(&self, _ctx: &MessageContext) -> Result<Option<Frame>> {
367            self.pipeline.update_parser(MessageParser::protobuf()).await;
368            Ok(Some(frame_with_system_command(
369                pong(),
370                Reliability::BestEffort,
371            )))
372        }
373    }
374
375    #[tokio::test]
376    async fn middleware_updates_do_not_wait_for_inflight_middleware_to_finish() {
377        let pipeline = MessagePipeline::new(MessageParser::json());
378        let (entered_tx, entered_rx) = oneshot::channel();
379        let (release_tx, release_rx) = oneshot::channel();
380        pipeline
381            .add_middleware(Arc::new(BlockingMiddleware {
382                entered_tx: Mutex::new(Some(entered_tx)),
383                release_rx: Mutex::new(Some(release_rx)),
384            }))
385            .await;
386
387        let frame = FrameBuilder::new()
388            .with_command(Command {
389                r#type: Some(
390                    crate::common::protocol::flare::core::commands::command::Type::System(ping()),
391                ),
392            })
393            .with_reliability(Reliability::BestEffort)
394            .build();
395        let processing = {
396            let pipeline = pipeline.clone();
397            tokio::spawn(async move { pipeline.process_frame(&frame, Some("conn-1")).await })
398        };
399
400        entered_rx.await.expect("blocking middleware should start");
401        let add_result = tokio::time::timeout(
402            std::time::Duration::from_millis(50),
403            pipeline.add_middleware(Arc::new(NoopMiddleware)),
404        )
405        .await;
406
407        let _ = release_tx.send(());
408        processing
409            .await
410            .expect("pipeline task should not panic")
411            .expect("pipeline should succeed");
412
413        assert!(
414            add_result.is_ok(),
415            "middleware updates should use a copy-on-write snapshot and avoid waiting for in-flight middleware"
416        );
417    }
418
419    #[tokio::test]
420    async fn process_raw_serializes_response_with_request_parser_snapshot() {
421        let json_parser = MessageParser::json();
422        let pipeline = MessagePipeline::new(json_parser.clone());
423        pipeline
424            .add_processor(Arc::new(ParserUpdatingProcessor {
425                pipeline: pipeline.clone(),
426            }))
427            .await;
428        let request = frame_with_system_command(ping(), Reliability::BestEffort);
429        let request_data = json_parser
430            .serialize(&request)
431            .expect("json request should serialize");
432
433        let response_data = pipeline
434            .process_raw(&request_data, Some("conn-1"))
435            .await
436            .expect("pipeline should process request")
437            .expect("processor should produce response");
438
439        let response = json_parser.parse_with_format(&response_data, SerializationFormat::Json).expect(
440            "response should use the same parser snapshot as request even if parser is updated mid-pipeline",
441        );
442        let format = response
443            .command
444            .and_then(|command| command.r#type)
445            .and_then(|kind| match kind {
446                crate::common::protocol::flare::core::commands::command::Type::System(system) => {
447                    SerializationFormat::try_from(system.format).ok()
448                }
449                _ => None,
450            })
451            .expect("response should be a system command");
452        assert_eq!(format, SerializationFormat::Protobuf);
453    }
454}