【直播切片工作台】第5章:程序入口与依赖装配

简介: 本章详解 `main.go` 这一唯一组合根:240行代码完成配置加载、基础设施初始化、10+对象构造注入、4类Worker与定时器启动,以及HTTP服务全生命周期管理。全程手工装配、依赖显式、fail-fast,体现“薄入口、接口先行、编排不落队列”的工程设计哲学。(239字)

第5章:程序入口与依赖装配

本章逐行解读 cmd/webserver/main.go——全书唯一的组合根(Composition Root)。240 行的 main 完成了配置加载、基础设施初始化、十余个对象的构造与注入、四组 Worker 与定时器的启动、HTTP 服务的生命周期管理。读懂它,整个系统的运行时拓扑就全部展开。

流程

main 的装配严格按依赖方向推进,任何一个环节失败立即 Fatal 退出(fail-fast):

  1. flag 解析 -config 路径 → config.Load 得到全局配置;
  2. bootstrap.InitLogger / bootstrap.InitDatabase / storage.NewClientFromAppConfig 初始化日志、连接池、对象存储;
  3. 构造五个 repository(account / live_material / video_project / llm_prompt / task);
  4. 构造下载器与 URL 重写器 → 三个 LLM 客户端实例(ASR 后处理 / 切片 / 对话各一份,同配置不同用途)→ ASR 服务与音频预处理器 → ASR Worker;
  5. 构造 capcutmate 客户端 → draft.Generator(组装 prepare + builder)→ 草稿 Worker → AI 切片 Worker → 一键成片 Worker(注入前两者形成编排);
  6. 构造各业务 service 并 new 出全部 handler;
  7. signal.NotifyContext 建立 ctx → 启动四个 Worker 与 scheduler → 注册 Gin 路由 → 起 HTTP goroutine;
  8. 阻塞等待 SIGINT/SIGTERM → 15 秒超时的 srv.Shutdown 优雅退出。

注意装配顺序里藏着一个关键设计:aiSliceDraftWorker 依赖 aiSliceWorkerdraftWorker接口(ProcessWithOptions 等方法),一键成片通过直接调用两者的阶段方法完成编排,而不是往任务队列里塞两个子任务——这保证了「AI 切片→草稿」在同一个 Task 行上顺序推进、进度连续(详见第 37 章)。

实现

main 中没有任何业务逻辑,只有构造与注入,这是维持「薄入口」的纪律。所有对象都是显式 new、显式传参,没有 wire/dig 之类的依赖注入框架——参数虽长(如 NewASRWorker 有 9 个参数),但依赖关系一眼可见,配合命名一致的构造函数,排查装配问题比反射注入容易得多。

值得逐个指出的装配细节:

  • 三个 LLM 客户端实例asrLLMsliceLLMchatLLM 使用相同配置但独立构造,为未来分化(不同模型/温度)预留了替换点,也让调用链在日志与单测中可区分。
  • media.NewFFmpegConverter("") / NewFFprobeProber(""):空串参数表示 PATH 查找 ffmpeg,Docker 镜像内置二进制,本地开发依赖系统安装。
  • "temp" 目录参数:音频预处理器把抽取的音频临时放在本地 temp,再上传对象存储给 ASR 远端读取。
  • scheduler 的两个 Jobcleanup-stagingcleanup-asr-staging,闭包捕获 cfg 直接调用 webroot.CleanupStaging,定时清理暂存目录(第 46 章)。
  • r.Use(gin.Recovery(), middleware.RequestLogger(logger)):中间件链只有两个,克制;/health/swagger/*any 在鉴权分组之外。
  • 优雅退出顺序:先 srv.Shutdown(等在途请求)再随 ctx 取消停 Worker;反过来的话 Worker 还可能写库时 HTTP 已拒绝健康检查。
  • _ "live-mixer/docs" 匿名导入触发 swaggo 生成的 docs.go 注册 Swagger 路由元数据。

📌 设计决策

  • 手工组合根而非 DI 框架:依赖图简单、编译期类型检查、新人可顺序阅读;代价是新增对象时要手动串线。
  • Worker 接口先行:AISliceWorkerDraftWorker 在 service 包内定义为接口,main 注入实现,ai_slice_worker_test.go 等用假实现替换,测试不需要数据库。
  • sync.Once 保证 Start 幂等(各 Worker 内部),main 里无需防重复启动。

代码示例

一键成片 Worker 的注入体现「编排者持有被编排者」:

// cmd/webserver/main.go(节选)
aiSliceDraftWorker := service.NewAISliceDraftWorker(
    taskRepo,
    videoProjectRepo,
    aiSliceWorker,   // 复用其 ProcessWithOptions:AI 切片阶段
    draftWorker,     // 复用其 Process:草稿阶段
    logger,
    cfg.Worker.AISliceDraftConcurrencyOrDefault(),
    cfg.Worker.AISliceDraftStaleTimeout(),
)

定时任务注册:Job 是纯数据 + 闭包,与业务 Worker 完全解耦:

// cmd/webserver/main.go(节选)
sched.Register(scheduler.Job{
   
    Name:     "cleanup-staging",
    Interval: cfg.Web.StagingCleanupInterval(),
    Run: func(context.Context) {
   
        removed, err := webroot.CleanupStaging(cfg.Web.RootDir, cfg.Web.StagingMaxDirs())
        if err != nil {
   
            logger.Warn("清理 staging 失败", zap.Error(err), zap.Int("removed", removed))
            return
        }
        if removed > 0 {
   
            logger.Info("已清理过期 staging 目录", zap.Int("removed", removed))
        }
    },
})

小结

  • main = 配置 → 基础设施 → 仓储 → 外部客户端 → Worker → service → handler → 路由 → 生命周期,方向永不回头。
  • 一键成片 Worker 通过接口复用两个子 Worker 的阶段方法,编排不落队列。
  • 优雅退出:HTTP 先关、Worker 随 ctx 停,15 秒兜底。

思考题

  1. 若把 Worker 拆成独立进程,main 需要改哪些装配段?接口边界是否已经足够?
  2. 三个 LLM 客户端实例共用一份配置,何时应该让 ASR 后处理与切片使用不同模型?

项目信息

  • GitHub仓库:github.com/Chyona/live-mixer
  • 项目案例:gogoshine.com
相关文章
|
19天前
|
人工智能 缓存 前端开发
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
DeepSeek Harness + DeepSeek V4 Pro 项目实战保姆级教程!手把手带你从零安装开源 AI 编程工具,开发架构图、知识讲解网站、3D 网页游戏、全栈 AI 应用 4 个项目,覆盖运行模式选择、插件安装与开发,看看能不能对标 Claude。
13113 84
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
|
7天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
2天前
|
缓存 人工智能 API
阿里云Qwen3.8‑Flash完整能力解析:模型特性、API调用实操与计费规则深度拆解
在AI应用快速落地的当下,开发者与企业选型大模型API,不再只单纯关注评测榜单分数,推理速度、上下文长度、多模态能力、工具调用稳定性以及实际调用成本,共同决定项目能否平稳上线。Qwen3.8‑Flash作为新一代多模态混合专家模型,主打高性能推理与低成本开销,面向编程开发、智能Agent工作流、超长文档解析、图文混合理解等高频场景,提供托管API服务,权重同时开放可供本地部署,兼容主流接口协议,能够无缝接入各类开发工具链。很多开发者在接入过程中,容易混淆普通按量Token计费、缓存计费、各类订阅计划之间的差异,造成实际账单超出预估。本文从模型底层架构、核心功能能力、适用场景、API调用实操、完
689 0
|
12天前
|
Web App开发 人工智能 API
16 个超火的 DeepSeek Harness 插件,大肥鱼已经落后 N 个版本了。。。
DeepSeek Harness 精选插件推荐合集,从图片识别、浏览器操控、多 Agent 协作到手机远程控制,一口气带你看完 DSH 社区热门的十几个插件,覆盖技能扩展、UI 界面增强、整活玩法三大类,让你的鲸鱼变得更强。
1735 4
|
13天前
|
人工智能 Java BI
【AI】DeepSeek Harness 安装、运行、管理插件
本文介绍了如何运行DeepSeek开源的Agent框架DeepSeek Harness(dsh)。主要内容包括:使用nvm安装适配的Node版本;通过代理加速克隆GitHub源码;使用pnpm安装依赖并启动项目;配置DeepSeek API Token;安装扩展功能的插件。该框架自带Web界面,支持模型适配、文件编辑等插件化功能
1918 1
|
人工智能 JavaScript 开发工具
DeepSeek Harness 本地安装与使用指南
DeepSeek Harness(DSH)是DeepSeek AI开源的Agent运行框架,支持本地文件操作、命令执行与工具调用。基于Cordis插件架构,具备高扩展性与强可控性,适合开发者搭建可控Agent环境或开展模型基准测试。当前为开发者预览版,需Node.js环境,推荐先用`npx @deepseek-ai/dsh web`快速体验。
5153 0
|
15天前
|
人工智能 JavaScript 测试技术
保姆级教程:DeepSeek Harness从安装到跑通测试,30分钟上手
DeepSeek Harness是DeepSeek开源的AI Agent运行时,主打“一行命令安装、5分钟跑通”。它让模型真正动手干活——读代码、跑测试、分析失败、生成修复方案。本文手把手教你30分钟从零上手,覆盖安装、配置、实测及避坑指南,助你快速掌握下一代AI编程范式。
|
8天前
|
人工智能 Linux iOS开发
Ollama使用教程:Ollama官网下载、Ollama本地部署大模型(2026最新)
Ollama 是一款免费开源的本地大模型运行工具,支持在 Windows/macOS/Linux 上离线运行 Qwen、DeepSeek、Llama 等主流开源模型,数据不出本机、隐私安全。提供 OpenAI 兼容 API,命令行一键拉取/运行/管理模型,无需联网,无调用限制,是开发者与 AI 爱好者部署本地 AI 助手的理想选择。(239 字)
|
14天前
|
人工智能 JavaScript 测试技术
从 0 到 1,DeepSeek Harness 保姆级安装与使用教程!
DeepSeek Harness是DeepSeek推出的开源Agent运行框架,秉持“一切皆插件”理念,支持模型、工具、技能、工作流等全模块自由替换与扩展。其核心Cordis内核实现动态插件管理,赋能Agent自进化。已成GitHub史上增速最快开源项目(15w+ Star),标志着国内大模型从拼价格转向重架构与生态的新拐点。
1348 6
从 0 到 1,DeepSeek Harness 保姆级安装与使用教程!

热门文章

最新文章