fix(message): resolve Phase 5-6 audit findings
- Add missing version column to all message tables (migration + entities) - Replace N+1 mark_all_read loop with single batch UPDATE query - Fix NotificationList infinite re-render (extract queryFilter to stable ref) - Fix NotificationPreferences dynamic import and remove unused Dayjs type - Add Semaphore (max 8) to event listener for backpressure control - Add /docs/openapi.json endpoint for API documentation - Add permission check to unread_count handler - Add version: Set(1) to all ActiveModel inserts
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use axum::Router;
|
||||
use axum::routing::{delete, get, put};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Semaphore;
|
||||
use uuid::Uuid;
|
||||
|
||||
use erp_core::error::AppResult;
|
||||
@@ -60,16 +62,23 @@ impl MessageModule {
|
||||
|
||||
/// 启动后台事件监听任务,将工作流事件转化为消息通知。
|
||||
///
|
||||
/// 使用 Semaphore 限制最大并发数为 8,防止事件突发时过度消耗资源。
|
||||
/// 在 main.rs 中调用,因为需要 db 连接。
|
||||
pub fn start_event_listener(db: sea_orm::DatabaseConnection, event_bus: EventBus) {
|
||||
let mut rx = event_bus.subscribe();
|
||||
let semaphore = Arc::new(Semaphore::new(8));
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
match rx.recv().await {
|
||||
Ok(event) => {
|
||||
let db = db.clone();
|
||||
let event_bus = event_bus.clone();
|
||||
let permit = semaphore.clone();
|
||||
|
||||
// 先获取许可,再 spawn 任务
|
||||
tokio::spawn(async move {
|
||||
let _permit = permit.acquire().await.unwrap();
|
||||
if let Err(e) =
|
||||
handle_workflow_event(&event, &db, &event_bus).await
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user