Gas Town Convoy Manager 深度解析:守护进程内的事件驱动车队完成检测与失联恢复机制

发布时间:2026/9/13 23:42:05
Gas Town Convoy Manager 深度解析:守护进程内的事件驱动车队完成检测与失联恢复机制 Gas Town Convoy Manager 深度解析守护进程内的事件驱动车队完成检测与失联恢复机制【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown导读Convoy车队是 Gas Town 中跨 rig 批量跟踪工作的核心单元但工作完成 → 车队关闭的最后一环长期以来依赖轮询式的 Deacon patrol存在单点失效。本文基于 spec.md 与 convoy_manager.go 等实现源码完整剖析ConvoyManager的双 goroutine 架构5s 事件轮询 30s 失联扫描、共享观察者CheckConvoysForIssue的调用链、12 条关键不变量与全部失败模式。读完你将掌握车队闭环如何做到事件驱动、幂等、可恢复以及如何通过测试矩阵验证这套机制。1. 问题背景完成闭环中的???断点Convoy 把相关工作分组但分组不等于驱动。在引入 ConvoyManager 之前完成依赖唯一的轮询通道——Deacon patrol 周期执行gt convoy check。当 Deacon 宕机或变慢时车队就会停滞任务全部完成但闭环永远不落地Create - Track - Execute - Issue closes - ??? - Convoy closesspec.md 明确指出这个缺口需要三项能力补齐事件驱动完成Event-driven completion——响应 issue 关闭事件而不是轮询等待失联恢复Stranded recovery——捕获事件驱动路径漏掉的车队崩溃、重启、陈旧状态冗余观测Redundant observation——多个观察者检测完成避免单一故障阻断闭环。与 convoy-lifecycle.md 中的问题陈述一致Convoy 是被动的跟踪器passive trackersspec 的目标是让车队主动收敛到完成actively converge on completion。2. 总体架构gt daemon内的双 goroutineConvoyManager是守护进程daemon常驻的组件运行在 convoy_manager.go 中由两个可被 context 取消、通过sync.WaitGroup协调关闭的 goroutine 组成Goroutine触发方式职责事件轮询Event poll每 5s 对所有 rig store hq store调用GetAllEventsSince检测EventClosed/EventStatusChanged(closed)对每个关闭事件调用convoy.CheckConvoysForIssue失联扫描Stranded scan每 30s 运行gt convoy stranded --json对ready_count 0的车队通过gt sling喂入第一个就绪 issue对空车队通过gt convoy check自动关闭两条 goroutine 之外Start()还会启动一个一次性启动清扫startup sweep延迟 10 秒运行一次scan()捕获守护进程停机期间或 Dolt 不可用期间完成的车队见源码 runStartupSweep。2.1 存储模型多 rig store hq store事件轮询会为所有已知 rig 打开 beads store来源是routes.jsonl路由表外加 town 级的 hq storeparked/docked 的 rig 在轮询时被跳过isRigParked回调nil 表示永不停泊。Convoy 查找永远使用 hq store因为 convoy 的 ID 是hq-*前缀只存在于 town 级数据库。每个 store 有独立的高水位线high-water mark互不干扰。2.2 共享观察者convoy.CheckConvoysForIssue事件轮询检测到关闭事件后调用的是 operations.go 中的共享函数CheckConvoysForIssue。它是所有观察者的统一入口观察者时机入口Daemon 事件轮询任一 rig store 或 hq store 检测到关闭事件convoy.CheckConvoysForIssue传入 hq store共享函数的核心步骤源码 CheckConvoysForIssue通过 SDKGetDependentsWithMetadatahq store过滤tracks依赖类型找到跟踪该 issue 的车队跳过已关闭的车队isConvoyClosed与处于 staged 状态未启动的车队isConvoyStaged状态以staged_开头对每个开放车队执行gt convoy check id若 check 后车队仍然开放则通过gt sling喂入下一个就绪 issue延续性喂入让喂入也变成事件驱动而非等待 patrol 轮询幂等——同一事件重复调用安全底层gt convoy check对已关闭车队天然无操作。2.3 关键设计决策spec.md 总结了六条设计决策均可在源码中得到印证决策理由SDK 轮询而非 CLI 流式避免子进程生命周期管理重启语义更简单高水位线原子 int64 / time.Time单调推进无重复事件处理每个车队每次扫描只喂一个 issue防止批量溢出下一个 issue 在下一次关闭事件时再喂失联扫描作为安全网捕获事件驱动路径漏掉的车队崩溃恢复store 为 nil 时仅禁用事件轮询无 beads SDK 时失联扫描仍可用降级模式解析二进制路径PATCH-006ConvoyManager 启动时解析gt/bd路径规避 PATH 问题3. 事件轮询的源码级剖析事件轮询由 runEventPoll 与 pollStore 实现源码中包含大量工程细节3.1 常量与时间参数const ( defaultStrandedScanInterval 30 * time.Second // 失联扫描默认间隔 eventPollInterval 5 * time.Second // 事件轮询间隔 eventPollMaxBackoff 60 * time.Second // 连续错误最大退避 eventPollLookback 1 * time.Second // 高水位回看窗口 convoyGracePeriod 5 * time.Minute // 新建车队的自动关闭豁免期 )1 秒回看lookbackDolt 中 beads 生命周期事件使用CURRENT_TIMESTAMP精度只有秒。若上一轮高水位与事件发生在同一秒内可能漏掉边界事件因此查询起点回退 1 秒配合processedLifecycleEvents去重避免重放。5 分钟宽限期grace period新建车队 5 分钟内免疫自动关闭防止失联扫描在 sling 的bd dep add尚未在 Dolt 中可见时误关车队对应 GH#2303测试见TestScanStranded_GracePeriodSkipsRecentConvoy。3.2 高水位线与预热warm-up每个 store 独立记录lastEventIDs默认起点是Unix epoch1970-01-01 UTC而非 Go 零值——因为 Go 的零值time.Time0001-01-01经 Dolt SQL driver 转成 float 参数会得到Inf触发Error 1366Unix epoch 对所有 SQL 后端安全。首个轮询周期只推进高水位、不处理事件seeded标志避免守护进程重启时重放整段历史事件造成事件洪峰。跨周期去重processedCloses记录当前关闭状态已被处理的 issue同一 close 事件可能因多 store 复制或高水位过滤不完美而重复出现GH#1798。当 issue 被**重新打开reopen**时清除标记使下一次关闭能被再次处理——对应close → reopen → close的完整生命周期。3.3 关闭事件判定func isCloseEvent(e *beadsdk.Event) bool { // EventClosed 直接判定为关闭 // EventStatusChanged 且 NewValue closed 判定为关闭 } func isReopenEvent(e *beadsdk.Event) bool { // EventReopened 判定为重开 // EventStatusChanged 且 OldValue closed、NewValue ! closed 判定为重开 }轮询对每条事件的处理顺序跳过空issue_id→ 记录/去重生命周期事件 → 重开则清除 close 去重并跳过 → 非关闭事件跳过 → 本轮seen去重 → 跨周期processedCloses去重 → 调用CheckConvoysForIssue并触发FireCrossRigDepNotifications跨 rig 依赖解除通知。3.4 错误处理与降级Dolt 数据损坏isInfNaNError识别Inf/-Inf/NaN is not a valid value for double错误历史版本以 Go 零值time.Time写入created_at导致直接将高水位推进到当前时间跳过坏行避免永久退避丢失的事件由失联扫描兜底。连续错误指数退避GetAllEventsSince报错后间隔翻倍上限 60sGH#2686成功后立即复位到 5s。recoveryMode事件轮询报错时置位失联扫描随后将间隔缩短为 5s 快速重试首次成功扫描后清除。懒打开lazy opening若 daemon 启动时 Dolt 尚未就绪stores为空通过openStores回调在每个 tick 重试直到 store 可用测试见TestEventPoll_LazyStoreOpening。hq store 缺失轮询到关闭事件但无 hq store 时记录日志跳过查找降级但不崩溃。4. 失联扫描的源码级剖析失联扫描由 runStrandedScan 驱动启动时立即执行一次之后按scanInterval0 或负数时默认 30s周期执行。4.1 数据来源gt convoy stranded --jsontype strandedConvoyInfo struct { ID string json:id Title string json:title TrackedCount int json:tracked_count ReadyCount int json:ready_count ReadyIssues []string json:ready_issues CreatedAt time.Time json:created_at BaseBranch string json:base_branch,omitempty }命令在 town root 下执行并使用只读路由环境bdReadOnlyRoutingEnvstdout 解析失败时把原始输出首行一并带进错误信息便于调试例如 stdout 上混入非 JSON 警告。4.2 扫描主循环三分支路由scan() 对每个失联车队按状态路由条件动作ReadyCount 0feedFirstReady(c)遍历ReadyIssues找到第一个可成功 dispatch 的 issueTrackedCount 0空车队closeEmptyConvoy若在 5 分钟宽限期内则跳过否则gt convoy check id自动关闭有 tracked 但 0 readycheckConvoyCompletion所有 tracked 都关闭 → 自动关闭情况 aissue 被阻塞/进行中 → check 是无操作情况 bscan()由scanMu互斥锁串行化防止runStrandedScan、runStartupSweep与 Dolt 恢复回调并发执行时对同一车队重复发起 check。4.3 喂入逻辑前缀 → rig 解析feedFirstReady的 dispatch 前置检查链源码 feedFirstReadyReadyIssues为空直接返回beads.ExtractPrefix(issueID)提取前缀无前缀则记录并跳过beads.GetRigNameForPrefix(townRoot, prefix)解析归属 rig查不到则跳过isRigParked(rig)为真则跳过parked rig 不派活执行gt sling issue rig --no-boot失败则继续尝试下一个 ready issue成功即返回每次扫描每个车队只喂一个。前缀 → rig 的两步解析spec 与 convoy-lifecycle.md 均有描述sh-pb6sa→ 提取前缀sh-→ 在~/gt/.beads/routes.jsonl中查{prefix:sh-,path:gastown/.beads}→ rig 名为gastown。实现位于 routes.go 的ExtractPrefixL252与GetRigNameForPrefixL456。前缀映射到path.town 级如hq-*时返回空 rig 名视为不可派发。5. 共享观察者CheckConvoysForIssue深度解析这是事件驱动路径的核心位于 operations.go。它同时承担完成检测与延续喂入两个职责。5.1 完成检测链路close event → getTrackingConvoys(issueID) // GetDependentsWithMetadata, 过滤 tracks 类型 → isConvoyClosed? // 已关闭则跳过 → isConvoyStaged? // staged_* 未启动则跳过 → runConvoyCheck(convoyID) // gt convoy check id幂等 → 仍开放? → feedNextReadyIssue() // 延续性喂入getTrackingConvoys用 SDKGetDependentsWithMetadata并只保留DependencyType tracks自然过滤掉blocks依赖isConvoyStaged采用fail-open读取失败视为非 staged避免因读不到状态而误跳过返回被检查的车队 ID 列表空表示该 issue 未被任何车队跟踪。5.2 就绪判定ready open 无 assignee 可派发 未阻塞feedNextReadyIssue按priority 升序数值小优先、同值按 ID 字典序排序后取第一个满足全部条件的 issue状态为open且无 assignee类型可派发IsSlingableType只有叶子工作项task/bug/feature/chore可派发空类型默认按 task 处理容器类型 epic、决策、消息、事件等排除未被阻塞依赖阻止isIssueBlocked前缀能解析出 rig 且 rig 未停泊gt sling issue rig --no-boot [--base-branchbranch]成功即返回base_branch 从 convoy 描述字段ParseConvoyFields中提取。5.3 阻塞依赖语义isIssueBlocked检查以下依赖类型中是否存在未关闭的目标var blockingDepTypes map[string]bool{ blocks: true, conditional-blocks: true, waits-for: true, merge-blocks: true, }parent-child特意不视为阻塞子任务在父 epic 未关闭时也可派发与 molecule step 行为一致tombstone状态永远视为未阻塞merge-blocks特殊语义仅closed不够必须CloseReason以Merged in 开头才确认代码真正合入防止在未合并的代码上派活GH#1893跨库精度优先通过StoreResolver到 issue 归属 rig store 查询新鲜状态规避 hq store 依赖元数据快照对跨 rig issue 的陈旧性GH#2624无 resolver 时回退到 hq store 快照或bd show --json子进程fetchCrossRigBeadStatus。5.4 跨库解析器 StoreResolver多 rig 场景下每个 rig 有独立 Dolt 数据库convoy 在 hq store 中却可能跟踪ds-*dashboard rig等异库 issue。不做跨库解析时跨库依赖会显示 0/0。multi_store.go 中的StoreResolver按前缀 → rig → store 分组用GetIssuesByIDs直接查归属 store 拿新鲜数据比子进程更快且不依赖bd。getConvoyTrackedIssues先用GetIssuesByIDs刷新未命中的 ID跨库走 resolver最后才回退到元数据快照或子进程。5.5 外部包装 ID 与安全防护extractIssueID剥离external:prefix:id包装格式还原真实 issue IDnil store 直接返回 nil无副作用nil logger 替换为 no-op不 panic幂等同一 issue 重复调用安全返回已检查的车队 ID 列表。6. 生命周期与守护进程集成6.1 daemon 集成点daemon.go 中的集成顺序对应 spec S-06daemon 启动时尝试打开 beads store失败则传入storeOpener懒重试回调构造NewConvoyManager(townRoot, logger, gtPath, scanInterval0, stores, storeOpener, isRigParked)0 间隔自动落到默认 30s在 feed curator 启动之后Start()若启用 Dolt server注册Dolt 恢复回调Dolt 从不健康恢复为健康时触发cm.scan()补扫停机期间完成的车队shutdown()中在 beads store 关闭之前Stop()正确的关闭顺序且必须在有界时间内完成。6.2 并发安全S-08Start()由started atomic.Bool的CompareAndSwap守卫重复调用为 no-op 并记录警告TestStart_DoubleCall_GuardedStop()幂等重复调用不死锁Stop()先于Start()时wg.Wait()立即返回TestConvoyManager_DoubleStop_IdempotentStop()会关闭其持有的全部 beads store无论先传入还是懒打开。6.3 子进程取消S-09所有子进程调用均使用exec.CommandContext(m.ctx, ...)并透传 context通过util.SetProcessGroup设置进程组daemon 关闭时用syscall.Kill(-pid, SIGKILL)杀掉整个进程组防止孤儿子进程。集成测试TestConvoyManager_ShutdownKillsHangingSubprocessconvoy_manager_integration_test.go验证即使gt子进程挂起daemon 也能在有界时间内完成关闭。6.4 二进制路径解析S-10CheckConvoysForIssue通过exec.LookPath(gt)解析二进制绝对路径失败回退裸gt并将gtPath贯穿到runConvoyCheck与dispatchIssue消除 PATH 依赖造成的行为漂移。7. 关键不变量Critical Invariantsspec.md 第 4 节归纳了 12 条不变量是整套机制的正确性契约#不变量类别影响半径故事已测试I-1Issue 关闭触发CheckConvoysForIssue数据高S-01是I-2非关闭事件零副作用安全低S-01是TestEventPoll_SkipsNonCloseEvents_NegativeAssertionI-3高水位线单调推进数据高S-01隐式I-4车队 check 幂等数据低S-03是I-5有就绪工作的失联车队被喂入活性高S-02是I-6空失联车队被自动关闭数据中S-02是I-7dispatch 失败后扫描继续活性中S-02是I-8context 取消能停掉两个 goroutine活性高S-06是I-9每次扫描每个车队只喂一个 issue安全中S-02隐式I-10未知前缀/rig 跳过 issue不崩溃安全中S-02是_UnknownPrefix_Skips、_UnknownRig_SkipsI-11Stop()幂等安全低S-08是I-12关闭时子进程取消活性高S-09是TestConvoyManager_ShutdownKillsHangingSubprocess8. 失败模式与恢复策略spec.md 第 5 节按三个子系统枚举了失败模式全部可在源码/测试中找到对应事件轮询失败可能性恢复已测试GetAllEventsSince报错低下个 5s 间隔重试指数退避是TestPollEvents_GetAllEventsSinceErrorbeads store 为 nil中事件轮询禁用失联扫描继续是关闭事件带空issue_id低跳过否列入剩余测试缺口CheckConvoysForIssuepanic低daemon 进程崩溃 → 重启否失联扫描失败可能性恢复已测试gt convoy stranded报错低记录日志跳过本轮是TestFindStranded_GtFailure_ReturnsErrorgt输出非法 JSON低记录日志跳过本轮是TestFindStranded_InvalidJSON_ReturnsErrorgt slingdispatch 失败中记录日志继续下一个车队是gt convoy check失败低记录日志继续下一个车队否issue 前缀未知低记录日志跳过该 issue是TestFeedFirstReady_UnknownPrefix_Skips前缀对应 rig 未知低记录日志跳过该 issue是TestFeedFirstReady_UnknownRig_Skipsgt子进程挂起低context 取消杀掉进程组是TestConvoyManager_ShutdownKillsHangingSubprocess生命周期失败可能性恢复已测试Stop()先于Start()低wg.Wait()立即返回否双重Stop()低幂等是双重Start()低atomic.Bool守卫no-op是TestStart_DoubleCall_Guarded子进程阻塞关闭低context 取消杀进程组是TestConvoyManager_ShutdownKillsHangingSubprocess9. 测试体系从单元测试到集成测试spec.md 的质量门要求所有实现故事必须通过go test ./...与golangci-lint run。测试覆盖经过三轮补强S-11 高影响半径不变量、S-12 错误路径、S-13 生命周期边界9.1 核心单元测试convoy_manager_test.go测试验证点TestEventPoll_DetectsCloseEvents真实 beads store 上创建关闭 issue验证检测日志TestEventPoll_SkipsNonCloseEvents/_NegativeAssertion只创建不关闭 → 无子进程调用、无车队活动零副作用TestScanStranded_FeedsReadyIssues/_ClosesEmptyConvoysmockgt验证 sling/check 日志文件TestScanStranded_GracePeriodSkipsRecentConvoy/_AllowsOldConvoy5 分钟宽限期边界TestScanStranded_NoStrandedConvoys空列表 → sling/check 日志均缺失负向断言TestScanStranded_DispatchFailure首次 sling 失败扫描继续TestFeedFirstReady_*只派发第一个就绪 issue未知前缀/rig/parked rig 跳过空ReadyIssues不崩溃TestFindStranded_GtFailure_ReturnsError/_InvalidJSON错误路径返回 errorTestScan_FindStrandedError_LogsAndContinues扫描失败不 panicTestPollEvents_GetAllEventsSinceError报错记日志下轮重试TestEventPoll_LazyStoreOpeningDolt 未就绪时的懒打开TestConvoyManager_ScanInterval_Configurable0 → 默认 30s自定义值保留TestConvoyManager_DoubleStop_Idempotent/TestStart_DoubleCall_Guarded生命周期边界TestStrandedConvoyInfo_JSONParsingJSON 往返解析9.2 集成测试convoy_manager_integration_test.go//go:build integrationTestConvoyManager_FullLifecycle完整启动/关闭TestConvoyManager_MultipleTrackingConvoys多车队跟踪TestConvoyManager_ParkedRig_SkipsFeedOnEventPoll停泊 rig 在事件轮询路径被跳过TestConvoyManager_ShutdownKillsHangingSubprocess挂起子进程下的有界关闭覆盖 I-12 与 S-09。9.3 测试基础设施S-14mockGtForScanTest(t, opts)共享构建器被 5 个扫描测试复用convoy_manager_test.go所有 mock 脚本写入调用日志文件负向测试断言日志文件不存在或为空隔离策略临时目录 t.Setenv(PATH)Windows 正确跳过无共享状态确定性测试用长间隔10 分钟ticker 避免真实计时竞态无真实时序依赖。spec.md 的harness scorecard五个维度Fixtures、Isolation、Observability、Speed、Determinism均为 4/5剩余缺口包括TestProcessLine_EmptyIssueID空 issue_id 的关闭事件与多 rig 事件轮询的集成覆盖扩充。10. 命令行手册与 ConvoyManager 配套的gt convoy命令车队的所有人工操作入口在 internal/cmd/convoy.go。ConvoyManager 的子进程调用stranded、check、sling正是这些命令的自动化消费方# 创建车队town 级 hq-* 前缀可跨 rig 跟踪 issue gt convoy create Deploy v2.0 gt-abc bd-xyz gt convoy create Release prep gt-abc --notify # 默认通知 mayor/ gt convoy create Feature rollout gt-a gt-b --owner mayor/ --notify ops/ gt convoy create Feature rollout gt-a gt-b gt-c --molecule mol-release gt convoy create --owned Manual deploy gt-abc # 调用方管理生命周期 gt convoy create Quick fix gt-abc --mergedirect # 绕过 refinery gt convoy create --from-epic gt-epic-abc # 从 epic 子任务自动发现 # 增查改 gt convoy status [convoy-id] # 进度、跟踪 issue、活跃 worker gt convoy list # 仪表盘视图--status open|closed 过滤 gt convoy add hq-cv-abc gt-issue1 gt-issue2 # 追加 issue关闭的车队自动重开 # 完成检测ConvoyManager 的核心调用 gt convoy check # 检查全部开放车队并自动关闭完成者 gt convoy check hq-cv-abc # 检查指定车队 gt convoy check --dry-run # 预演不实际关闭 # 失联扫描ConvoyManager 30s 调用的数据源 gt convoy stranded # 找失联车队 gt convoy stranded --json # 机器可读输出 # 人工关闭与落地 gt convoy close hq-cv-abc --reasonwork done differently gt convoy close hq-cv-xyz --force # 强制关闭跟踪项未完成也可 gt convoy land hq-cv-abc # 拥有者落地清理 worktree 关闭语义要点源码Long描述tracks关系是非阻塞的跟踪 issue 不阻塞车队车队可跨前缀跟踪hq 车队跟踪gt-*、bd-*issuelanded 所有跟踪 issue 关闭 → 通知订阅者。close默认校验跟踪项全部关闭--force跳过校验land专用于--owned车队。10.1gt sling的自动建队convoy-lifecycle.md 补充了创建路径gt sling每次派发都会自动创建车队除非--no-convoy。单 bead sling 建 1 车队批量 sling3 argsrig 由前缀经routes.jsonl自动解析建1 个共享车队跟踪全部 beads并行 spawn polecat间隔 2s--max-concurrent默认 0 表示不限。批量中任一 bead 已被其他车队跟踪时整批在 spawn 前报错并给出 4 条建议动作。初始批量派发不做依赖检查并行全派而关闭事件后的事件驱动喂入才严格检查IsSlingableType与isIssueBlocked。11. MR beads 中的车队追踪字段S-07为实现合并队列的优先级打分与防饥饿starvation preventionMR beads 携带车队追踪字段实现在 internal/beads/fields.gotype MRFields struct { // ... ConvoyID string // 父车队 ID如 hq-cv-abc ConvoyCreatedAt string // 车队创建时间ISO 8601用于防饥饿 }解析与格式化支持下划线、连字符、camelCase三种键名变体格式化输出为convoy_id:与convoy_created_at:两行写入 bead 描述字段由 refinery 用于合并队列的优先级打分车队越早创建、待处理越久优先级越高防止长期饥饿。12. 演进教训观察者的合并与根路径 BugS-04/S-05/S-17/S-18spec 记录了重要的架构演进——从多观察者走向单一观察者S-04 Witness 观察者移除daemon 的多 rig 事件轮询覆盖全部 rig 库 hq已提供事件驱动覆盖30s 失联扫描兜底witness 的核心职责是 polecat 生命周期管理车队跟踪与之正交。原 6 处CheckConvoysForIssueWithAutoStore调用点1 处 post-merge、5 处 zombie 清理路径均为纯副作用通知钩子已删除。S-05 Refinery 观察者移除在功能整个生命周期内一直静默失效S-17 发现传错根路径却无可见影响反向证明另两个观察者已足够且 beads 不可用会禁用整个 town不只是车队检查降级模式需要第三观察者的理由不成立。S-17 根路径验证refinery 传e.rig.PathtownRoot/rigName给CheckConvoysForIssueWithAutoStore而OpenStoreForTown构造path/.beads/dolt——于是打开了townRoot/rigName/.beads/dolt而非townRoot/.beads/dolt。rig 级.beads/通常是重定向文件或 rig 级元数据不含车队依赖数据导致beadsdk.Open失败或打开无车队数据的 storeCheckConvoysForIssueWithAutoStore静默返回 nil从 refinery 观察者角度车队检查实际被禁用。对照witness 用workspace.Find(workDir)解析 town rootdaemon 直接传d.config.TownRoot。S-18 修复engineer.go改用workspace.Find(e.rig.Path)解析 town root 后再调用与 witness 模式一致town root 找不到时优雅回退并移除BUG(S-17)注释。13. 非目标与未来工作spec.md 第 8 节明确这些内容不在本 spec 范围内详见 convoy-lifecycle.md 的 P2/P3 规划车队 owner/requester 字段与定向通知P2车队超时/SLAdue_at字段、超期浮出P3显式gt convoy reopen命令当前通过 add 隐式重开ConvoyManager 的测试时钟注入P3当前用time.Ticker30s 默认值测试用长间隔规避真实计时提议增加clock字段接口NewTicker(d)让所有周期型 daemon 组件受益。14. 文件地图角色文件内容核心实现internal/daemon/convoy_manager.goConvoyManager事件轮询 失联扫描 启动清扫 goroutine共享观察者internal/convoy/operations.goCheckConvoysForIssue、feedNextReadyIssue、getTrackingConvoys、IsSlingableType、isIssueBlocked、FireCrossRigDepNotifications跨库解析internal/convoy/multi_store.goStoreResolver前缀路由到 rig store 的新鲜状态解析前缀路由internal/beads/routes.goExtractPrefix、GetRigNameForPrefix、GetRigPathForPrefixroutes.jsonl 解析车队字段internal/beads/fields.goMRFields.ConvoyID、MRFields.ConvoyCreatedAtdaemon 集成internal/daemon/daemon.go启动/停止 ConvoyManager、懒打开、Dolt 恢复回调CLIinternal/cmd/convoy.gogt convoy create/status/list/add/check/stranded/close/land自动建队internal/cmd/sling_convoy.gosling 过程中的自动车队创建单元测试internal/daemon/convoy_manager_test.go22 个单元测试集成测试internal/daemon/convoy_manager_integration_test.go//go:build integration含挂起子进程关闭测试操作函数测试internal/convoy/operations_test.go、internal/convoy/store_test.go边界用例与安全守卫生命周期文档docs/design/convoy/convoy-lifecycle.md问题陈述、设计原则、Mermaid 流程图规范文档docs/design/convoy/spec.md本 spec故事、不变量、失败模式、文件地图概念文档docs/concepts/convoy.mdConvoy 概念与使用方式总结ConvoyManager用事件驱动 周期安全网 共享幂等观察者三件套把车队完成闭环从 Deacon 的单点轮询解放出来。5s 事件轮询保证时效30s 失联扫描 启动清扫 Dolt 恢复回调保证可靠性CheckConvoysForIssue的幂等性与跨库StoreResolver保证正确性而 12 条不变量与三层测试矩阵单元/集成/负向断言把这个并发系统约束在可验证的安全边界内。若你正在设计批处理任务自动收敛类系统这套事件轮询 兜底扫描 幂等检查器的组合与它的失败模式清单是可直接借鉴的工程范本。【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询