Version: 0.9.56.dev.260429

后端:
1. 启动层完成第一轮运行边界拆分,新增 `all / api / worker` 三种进程模式:`all` 保持原单体行为,`api` 只启动 Gin 与同步业务依赖,`worker` 只启动 outbox、Kafka consumer 与 memory worker。
2. 启动装配从单个入口拆成 runtime 依赖图,配置、DB、Redis、RAG、memory、DAO、Service、Handler、newAgent 依赖统一集中构造,再按进程角色选择启动 HTTP 或后台循环。
3. outbox 事件总线补齐 dispatch / consume 分离启动能力,支持后续 relay 与 consumer 独立进程化,同时保留原组合启动语义。
4. 核心 outbox handler 注册收口为公共接线入口,统一校验依赖并复用注册顺序,避免 api / worker / all 多入口复制事件注册逻辑。

迁移说明:
5. 本轮只迁运行边界,不拆业务服务边界;旧单体入口仍保留并默认走 `all` 兼容模式,当前切流点是 API 不再消费异步事件,worker 承担后台消费与 memory 任务。
6. 补充微服务四步迁移与第二阶段并行开发计划,明确先拆 API/Worker,再接主动调度与飞书通知,后续再拆 notification、active-scheduler、schedule/task。
This commit is contained in:
Losita
2026-04-29 17:44:42 +08:00
parent d5b52b35ac
commit 7d21b6516f
8 changed files with 1097 additions and 200 deletions

View File

@@ -144,7 +144,33 @@ func (e *Engine) Start(ctx context.Context) {
log.Printf("Kafka topic is ready: %s", e.topic)
}
e.StartDispatch(ctx)
e.StartConsume(ctx)
}
// StartDispatch 单独启动 outbox -> Kafka 的投递循环。
//
// 职责边界:
// 1. 只负责启动 dispatch 后台 goroutine不负责启动 Kafka 消费;
// 2. 不重复执行 Start 中的 topic readiness 等待,避免改变原 Start(ctx) 的启动语义;
// 3. ctx 取消后由内部循环自行退出,调用方无需额外停止 goroutine。
func (e *Engine) StartDispatch(ctx context.Context) {
if e == nil {
return
}
go e.startDispatchLoop(ctx)
}
// StartConsume 单独启动 Kafka -> handler 的消费循环。
//
// 职责边界:
// 1. 只负责启动 consume 后台 goroutine不负责扫描或投递 outbox
// 2. 不注册业务 handlerhandler 仍由 RegisterEventHandler 显式注入;
// 3. ctx 取消或 consumer 返回 context.Canceled 时,内部循环按既有逻辑退出。
func (e *Engine) StartConsume(ctx context.Context) {
if e == nil {
return
}
go e.startConsumeLoop(ctx)
}

View File

@@ -78,6 +78,32 @@ func (b *EventBus) Start(ctx context.Context) {
b.engine.Start(ctx)
}
// StartDispatch 单独启动事件总线的 outbox 投递循环。
//
// 职责边界:
// 1. 只暴露 relay/dispatch 运行职责,便于独立进程只负责投递;
// 2. 不启动消费循环,避免与独立 consumer 进程争抢职责;
// 3. 不改变 Start(ctx) 的既有组合启动行为。
func (b *EventBus) StartDispatch(ctx context.Context) {
if b == nil || b.engine == nil {
return
}
b.engine.StartDispatch(ctx)
}
// StartConsume 单独启动事件总线的 Kafka 消费循环。
//
// 职责边界:
// 1. 只暴露 consumer 运行职责,便于独立进程只负责消费;
// 2. 不扫描 outbox、不投递 Kafka状态推进仍复用 Engine 既有逻辑;
// 3. handler 注册仍由调用方在启动前显式完成。
func (b *EventBus) StartConsume(ctx context.Context) {
if b == nil || b.engine == nil {
return
}
b.engine.StartConsume(ctx)
}
// Close 关闭事件总线资源producer/consumer
func (b *EventBus) Close() {
if b == nil || b.engine == nil {