feat(core): 事件归档 + 消费者幂等性 — 迁移 084/085 + 清理任务
- 迁移 084: domain_events_archive 归档表 + cleanup_old_published_events() - 迁移 085: processed_events 去重表 + cleanup_old_processed_events() - erp-core: is_event_processed() / mark_event_processed() 幂等性辅助 - erp-server: tasks::start_event_cleanup() 每 24h 归档 >90 天事件
This commit is contained in:
@@ -4,6 +4,7 @@ mod handlers;
|
||||
mod middleware;
|
||||
mod outbox;
|
||||
mod state;
|
||||
mod tasks;
|
||||
|
||||
/// OpenAPI 规范定义 — 通过 utoipa derive 合并各模块 schema。
|
||||
#[derive(OpenApi)]
|
||||
@@ -410,6 +411,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
outbox::start_outbox_relay(db.clone(), event_bus.clone(), config.database.url.clone());
|
||||
tracing::info!("Outbox relay started");
|
||||
|
||||
// Start event cleanup (archive old published events + purge processed_events)
|
||||
tasks::start_event_cleanup(db.clone());
|
||||
|
||||
// Start timeout checker (scan overdue tasks every 60s)
|
||||
erp_workflow::WorkflowModule::start_timeout_checker(db.clone(), event_bus.clone());
|
||||
tracing::info!("Timeout checker started");
|
||||
|
||||
53
crates/erp-server/src/tasks.rs
Normal file
53
crates/erp-server/src/tasks.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use std::time::Duration;
|
||||
|
||||
/// 启动事件清理后台任务。
|
||||
///
|
||||
/// 每日执行一次:
|
||||
/// - 调用 `cleanup_old_published_events()` 归档 >90 天的已发布事件
|
||||
/// - 调用 `cleanup_old_processed_events()` 清理 >7 天的去重记录
|
||||
pub fn start_event_cleanup(db: sea_orm::DatabaseConnection) {
|
||||
tokio::spawn(async move {
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(86400));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
if let Err(e) = run_cleanup(&db).await {
|
||||
tracing::warn!(error = %e, "事件清理任务执行失败");
|
||||
}
|
||||
}
|
||||
});
|
||||
tracing::info!("事件清理任务已启动(每 24 小时执行一次)");
|
||||
}
|
||||
|
||||
async fn run_cleanup(db: &sea_orm::DatabaseConnection) -> Result<(), sea_orm::DbErr> {
|
||||
use sea_orm::ConnectionTrait;
|
||||
|
||||
// 归档 >90 天的已发布事件
|
||||
match db
|
||||
.execute_unprepared("SELECT cleanup_old_published_events(90, 1000)")
|
||||
.await
|
||||
{
|
||||
Ok(result) => {
|
||||
tracing::info!(
|
||||
rows_affected = result.rows_affected(),
|
||||
"已发布事件归档完成"
|
||||
);
|
||||
}
|
||||
Err(e) => tracing::warn!(error = %e, "已发布事件归档失败"),
|
||||
}
|
||||
|
||||
// 清理 >7 天的去重记录
|
||||
match db
|
||||
.execute_unprepared("SELECT cleanup_old_processed_events(7, 1000)")
|
||||
.await
|
||||
{
|
||||
Ok(result) => {
|
||||
tracing::info!(
|
||||
rows_affected = result.rows_affected(),
|
||||
"去重记录清理完成"
|
||||
);
|
||||
}
|
||||
Err(e) => tracing::warn!(error = %e, "去重记录清理失败"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user