Version: 0.9.64.dev.260503

后端:
1. 服务级 outbox 基础设施全量落地——新增 service route / service catalog / route registry,重构 outbox engine、repository、event bus 和 model,按 `event_type -> service -> table/topic/group` 统一写入与投递,保留 `agent` 兼容壳但不再依赖共享 outbox
2. Kafka 投递、消费与启动装配同步切换——更新 kafka config、consumer、envelope,接入服务级 topic 与 consumer group,并同步调整 mysql 初始化、start/main/router 装配,保证各服务 relay / consumer 独立装配
3. 业务事件处理器按服务归属重接新 bus——`active-scheduler` 触发链路,以及 `agent` / `memory` / `notification` / `task` 相关 outbox handler 统一切到新路由注册与服务目录,避免新流量回流共享表
4. 同步更新《微服务四步迁移与第二阶段并行开发计划》,把阶段 1 改成当前基线并补齐结构图、阶段快照、风险回退和多代理执行口径
This commit is contained in:
Losita
2026-05-03 20:29:00 +08:00
parent 166fb1b507
commit a6c1e5d077
28 changed files with 1631 additions and 340 deletions

View File

@@ -2,11 +2,12 @@ package events
import (
"errors"
"fmt"
"github.com/LoveLosita/smartflow/backend/dao"
outboxinfra "github.com/LoveLosita/smartflow/backend/infra/outbox"
"github.com/LoveLosita/smartflow/backend/memory"
"github.com/LoveLosita/smartflow/backend/notification"
sharedevents "github.com/LoveLosita/smartflow/backend/shared/events"
)
// RegisterCoreOutboxHandlers 注册核心业务 outbox handler。
@@ -15,9 +16,9 @@ import (
// 1. 只负责聚合注册当前核心业务 handler便于 start / worker/all 等启动入口复用同一套接线顺序。
// 2. 不负责创建 eventBus/outboxRepo/DAO/memoryModule也不负责启动或关闭事件总线。
// 3. 不改变单个 Register* 函数的职责;具体 payload 解析、幂等消费和业务落库仍由各自 handler 负责。
// 4. 入口先完整校验依赖,避免注册到一半才发现依赖缺失,导致事件总线处于半注册状态
// 4. 这里以显式 route table 的方式列出“事件类型 -> 服务归属 -> handler”避免后续新增事件时只改启动入口不改接线表
func RegisterCoreOutboxHandlers(
eventBus *outboxinfra.EventBus,
eventBus OutboxBus,
outboxRepo *outboxinfra.Repository,
repoManager *dao.RepoManager,
agentRepo *dao.AgentDAO,
@@ -28,28 +29,39 @@ func RegisterCoreOutboxHandlers(
return err
}
// 1. 按照现有 start.go 的接线顺序注册,保证迁移到 worker/all 后消费行为不发生隐式变化。
// 2. 每一步只包一层业务语义错误,便于启动日志直接定位是哪类 handler 注册失败。
if err := RegisterChatHistoryPersistHandler(eventBus, outboxRepo, repoManager); err != nil {
return fmt.Errorf("注册聊天历史持久化 handler 失败: %w", err)
}
if err := RegisterTaskUrgencyPromoteHandler(eventBus, outboxRepo, repoManager); err != nil {
return fmt.Errorf("注册任务紧急度平移 handler 失败: %w", err)
}
if err := RegisterChatTokenUsageAdjustHandler(eventBus, outboxRepo, repoManager); err != nil {
return fmt.Errorf("注册会话 token 调整 handler 失败: %w", err)
}
if err := RegisterAgentStateSnapshotHandler(eventBus, outboxRepo, repoManager); err != nil {
return fmt.Errorf("注册 agent 状态快照 handler 失败: %w", err)
}
if err := RegisterAgentTimelinePersistHandler(eventBus, outboxRepo, agentRepo, cacheRepo); err != nil {
return fmt.Errorf("注册 agent 时间线持久化 handler 失败: %w", err)
}
if err := RegisterMemoryExtractRequestedHandler(eventBus, outboxRepo, memoryModule); err != nil {
return fmt.Errorf("注册记忆抽取 handler 失败: %w", err)
return registerOutboxHandlerRoutes(coreOutboxHandlerRoutes(eventBus, outboxRepo, repoManager, agentRepo, cacheRepo, memoryModule))
}
// RegisterAllOutboxHandlers 注册当前阶段所有 outbox handler。
//
// 职责边界:
// 1. 只负责把 core / active_scheduler / notification 三类路由一次性接线;
// 2. 不负责创建依赖,也不负责启动事件总线;
// 3. 供当前启动流程在“总线启动前”统一完成显式路由注册。
func RegisterAllOutboxHandlers(
eventBus OutboxBus,
outboxRepo *outboxinfra.Repository,
repoManager *dao.RepoManager,
agentRepo *dao.AgentDAO,
cacheRepo *dao.CacheDAO,
memoryModule *memory.Module,
activeTriggerWorkflow ActiveScheduleTriggeredProcessor,
notificationService *notification.NotificationService,
) error {
if err := validateAllOutboxHandlerDeps(eventBus, outboxRepo, repoManager, agentRepo, cacheRepo, memoryModule, activeTriggerWorkflow, notificationService); err != nil {
return err
}
return nil
return registerOutboxHandlerRoutes(allOutboxHandlerRoutes(
eventBus,
outboxRepo,
repoManager,
agentRepo,
cacheRepo,
memoryModule,
activeTriggerWorkflow,
notificationService,
))
}
// validateCoreOutboxHandlerDeps 校验核心 outbox handler 聚合注册所需依赖。
@@ -58,7 +70,7 @@ func RegisterCoreOutboxHandlers(
// 1. 只做 nil 校验不做数据库、Redis、Kafka 连通性探测,避免注册函数承担启动健康检查职责。
// 2. 返回 error 表示依赖缺失;返回 nil 表示可以安全进入逐项注册流程。
func validateCoreOutboxHandlerDeps(
eventBus *outboxinfra.EventBus,
eventBus OutboxBus,
outboxRepo *outboxinfra.Repository,
repoManager *dao.RepoManager,
agentRepo *dao.AgentDAO,
@@ -85,3 +97,112 @@ func validateCoreOutboxHandlerDeps(
}
return nil
}
// validateAllOutboxHandlerDeps 在核心依赖基础上,额外校验 active_scheduler 和 notification 相关依赖。
func validateAllOutboxHandlerDeps(
eventBus OutboxBus,
outboxRepo *outboxinfra.Repository,
repoManager *dao.RepoManager,
agentRepo *dao.AgentDAO,
cacheRepo *dao.CacheDAO,
memoryModule *memory.Module,
activeTriggerWorkflow ActiveScheduleTriggeredProcessor,
notificationService *notification.NotificationService,
) error {
if err := validateCoreOutboxHandlerDeps(eventBus, outboxRepo, repoManager, agentRepo, cacheRepo, memoryModule); err != nil {
return err
}
if activeTriggerWorkflow == nil {
return errors.New("active schedule triggered processor is nil")
}
if notificationService == nil {
return errors.New("notification service is nil")
}
return nil
}
// coreOutboxHandlerRoutes 只描述 core 阶段的 outbox 路由。
func coreOutboxHandlerRoutes(
eventBus OutboxBus,
outboxRepo *outboxinfra.Repository,
repoManager *dao.RepoManager,
agentRepo *dao.AgentDAO,
cacheRepo *dao.CacheDAO,
memoryModule *memory.Module,
) []outboxHandlerRoute {
return []outboxHandlerRoute{
{
EventType: EventTypeChatHistoryPersistRequested,
Service: outboxHandlerServiceAgent,
Register: func() error {
return RegisterChatHistoryPersistHandler(eventBus, outboxRepo, repoManager)
},
},
{
EventType: EventTypeTaskUrgencyPromoteRequested,
Service: outboxHandlerServiceTask,
Register: func() error {
return RegisterTaskUrgencyPromoteHandler(eventBus, outboxRepo, repoManager)
},
},
{
EventType: EventTypeChatTokenUsageAdjustRequested,
Service: outboxHandlerServiceAgent,
Register: func() error {
return RegisterChatTokenUsageAdjustHandler(eventBus, outboxRepo, repoManager)
},
},
{
EventType: EventTypeAgentStateSnapshotPersist,
Service: outboxHandlerServiceAgent,
Register: func() error {
return RegisterAgentStateSnapshotHandler(eventBus, outboxRepo, repoManager)
},
},
{
EventType: EventTypeAgentTimelinePersistRequested,
Service: outboxHandlerServiceAgent,
Register: func() error {
return RegisterAgentTimelinePersistHandler(eventBus, outboxRepo, agentRepo, cacheRepo)
},
},
{
EventType: EventTypeMemoryExtractRequested,
Service: outboxHandlerServiceMemory,
Register: func() error {
return RegisterMemoryExtractRequestedHandler(eventBus, outboxRepo, memoryModule)
},
},
}
}
// allOutboxHandlerRoutes 把当前阶段所有 outbox 路由一次性展开,供启动入口统一接线。
func allOutboxHandlerRoutes(
eventBus OutboxBus,
outboxRepo *outboxinfra.Repository,
repoManager *dao.RepoManager,
agentRepo *dao.AgentDAO,
cacheRepo *dao.CacheDAO,
memoryModule *memory.Module,
activeTriggerWorkflow ActiveScheduleTriggeredProcessor,
notificationService *notification.NotificationService,
) []outboxHandlerRoute {
routes := coreOutboxHandlerRoutes(eventBus, outboxRepo, repoManager, agentRepo, cacheRepo, memoryModule)
routes = append(routes,
outboxHandlerRoute{
EventType: sharedevents.ActiveScheduleTriggeredEventType,
Service: outboxHandlerServiceActiveScheduler,
Register: func() error {
return RegisterActiveScheduleTriggeredHandler(eventBus, outboxRepo, activeTriggerWorkflow)
},
},
outboxHandlerRoute{
EventType: sharedevents.NotificationFeishuRequestedEventType,
Service: outboxHandlerServiceNotification,
Register: func() error {
return RegisterFeishuNotificationHandler(eventBus, outboxRepo, notificationService)
},
},
)
return routes
}