Kun 排队输入交付链路可靠性实战指南:从 admissionPending 故障到两阶段提交、租约与幂等恢复

发布时间:2026/10/10 8:46:45
Kun 排队输入交付链路可靠性实战指南:从 admissionPending 故障到两阶段提交、租约与幂等恢复
人工智能AI Agent自主智能体桌面应用MCP Clients【免费下载链接】KunLocal-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.项目地址https://gitcode.com/gh_mirrors/de/Kun点击查看免费下载导读本文基于 Kun 开源仓库中的故障复盘文档 排队输入交付链路故障与修复说明完整还原 2026-09-08 发生的「输入停留在admissionPending、队列停滞」事故根因并深入源码讲解 Kun 的排队输入交付链路如何通过执行租约execution lease、两阶段提交two-phase admission、准确 turn ID 回滚、每线程退避重试与clientRequestId幂等构建可恢复、可确认的队列语义。读完本文你将掌握GET /v1/threads/:id/queued-turns回执契约的字段含义、故障注入验证思路以及在线与启动恢复的统一规则可直接用于排查 Kun 排队场景中的「疑似丢消息」「前端误确认送达」等问题。一、事故复盘两条输入为何卡在 admissionPending2026-09-08 的故障中两条输入停留在admissionPending状态queued turn 的元数据已经写入但 canonical user itemsession 中的用户消息条目尚未写入Manager 返回stale_turn_fence原回合完成后队列也没有继续推进。从源码结构看admissionPending是 Kun turn 记录上的一个可选标记见 contracts/turns.ts 中admissionPending: z.literal(true).optional()它标志着一个排队 turn 正处于「元数据已落盘、提交尚未完成」的中间态。stale_turn_fence则来自 Manager 侧的执行租约校验见 service-manager-state.ts表示当前线程持有的 fence 已过期、不再有权限执行写入。文档将根因归纳为六个相互叠加的问题queued turn 没有执行租约写正文时未使用当前线程的有效租约跨线程写入被拒后留下半成品turn ID 保存过晚ID 在整个写入函数返回后才保存途中失败无法按准确 ID 精确回滚两个 busy enqueue 分支不一致提交与恢复逻辑分叉行为不可预期查询接口把未提交记录当可执行队列前端据此误确认「已送达」调度器缺少独立重试遇到一次阻塞或失败后只等待外部事件没有自愈能力排队时提前发布 user-item 事件前端据此切换了当前回合与实际执行状态不一致。这六点实际上覆盖了数据层提交顺序与回滚、并发层租约与 fence、调度层重试与暂停、接口层回执语义与事件层事件发布时机是理解后续所有修复设计的入口。二、提交与权限租约授权、串行提交与两阶段入队修复后的核心设计围绕「一次入队 一个原子的两阶段提交」展开。2.1 执行租约与 fence 语义当前有效执行租约只授权同一线程内的写入包括另一条待执行输入跨线程写入仍被拒绝。旧回合捕获的 fence 仍保持旧代际generation不能借用新租约这正是stale_turn_fence的保护意义所在——防止旧回合在释放后继续篡改新回合的数据。从源码看队列提升逻辑中startNextQueuedTurn会先检查executionLeases?.owner(threadId)见 turn-service-queue-operations.ts若线程仍被其他 Runtime 持有租约则直接返回绝不越权提升。2.2 串行提交函数与准确 turn ID调度器离开上一回合的异步 fence 上下文独立提升下一条输入busy 输入统一经过一个串行提交函数enqueueTurnDurably在第一笔写入之前保存准确的 turn IDattemptedTurnId ids.next(turn)失败时可精确回滚见 queue-admission.ts。2.3 两阶段提交顺序提交顺序固定为pending 元数据 → canonical user item → 完成标记Phase 1persistQueuedTurnRecord以 revision CAS 写入 queued turn 记录含admissionPending: true再追加 session user itemitem_${turnId}_user。CAS 冲突时重读、重查队列上限最多重试 3 次见 turn-service-queue-operations.ts。Phase 2completeQueuedTurnAdmission调用markTurnAdmissionCompleted标记提交完成并记录turn_queued事件返回queuedResponse。途中失败按准确 ID 回滚rollbackPendingAdmission若只是完成响应丢失则查询后确认原提交——即「观察精确 admission 后再决定回滚还是重试」代码中 catch 分支会先读取admissionCompletedAt已存在且admissionPending已清除的记录直接返回 queued 响应或幂等重放避免重复建 turn。2.4 clientRequestId 幂等同一个clientRequestId在锁内重新核对enqueueTurnDurably在withManagerDataMutex(thread:...)锁内查找同 ID 既有记录比对clientRequestFingerprint对 start request 的 SHA-256 指纹见 contracts/turns.ts指纹不一致抛TurnConflictError相同则走幂等重放不重复建立已提交 turn。2.5 在线与启动恢复统一规则正文存在 → 补齐提交reconcilePendingQueueAdmission中若 session 已存在该 turn 的user_messageitem则调用markTurnAdmissionCompleted完成提交正文不存在 → 回滚否则调用rollbackPendingAdmission读取失败不能当作「正文不存在」读取异常时抛QueueAdmissionUncertainError交由上层重试而非误回滚见 queue-admission.ts。该逻辑同时被在线路径enqueue 时发现同 ID pending 记录和启动恢复路径reconcilePendingQueueAdmissions扫描线程全部 pending turn复用。2.6 事件发布时机排队正文持久化后不立即发布执行事件只有真正提升promote时startNextQueuedTurn才发布turn_started/item_created事件使前端当前回合与实际执行保持一致。这正是修复根因第 6 点此前排队即发布 user-item 事件导致前端误切换当前回合。三、调度、停止与关闭退避重试与暂停语义每线程退避重试临时写入失败、CAS 冲突或租约阻塞时间隔从250 毫秒递增最高 5 秒提升成功和队列清空会取消重试计时器。文档中「可选直到实现添加重试计时器销毁」的测试注释也印证了重试机制的可注入设计见 queue-manager-integration.test.ts。Stop 暂停Stop 暂停本线程后续输入租约释放产生的容量通知不会解除暂停。显式继续或新的队列提交才恢复调度。租约释放时序本地执行槽立即释放Manager 确认租约释放后再通知调度器。应用关闭取消重试计时器并等待正在进行的提升操作结束。提升路径内部还包含两类防护队列候选若仍admissionPending则跳过不提升绝不提升未提交行若 durable admission 快照已无法应用如 Design 面/Profile 锁已迁移则以QUEUE_ADMISSION_FAILED_CODE失败码定义见 turn-service-queue-operations.ts原地失败该候选并继续尝试下一条CAS 冲突时回滚刚获取的租约与 admission重新读取后再决策。四、客户端契约无正文回执与不确定性提示GET /v1/threads/:id/queued-turns路由实现见 thread-queued-turns.tsSchema 见 contracts/turns.ts返回无正文回执三类字段语义如下字段含义queuedTurns已提交、等待执行的输入含turnId、可选clientRequestId、position、createdAtpendingAdmissions提交尚未确认可按请求 ID 恢复含turnId、clientRequestId、createdAtsettledTurns已开始或已结束的 turn含可选terminalCode4.1 部分提交失败的错误语义部分提交失败返回HTTP 503和queue_admission_uncertain错误类见 queue-admission.ts附带请求 ID、失败阶段prepare/recover/persist/commit/rollback及可重试标记。原始 Manager 错误只记录在运行日志不向客户端暴露内部细节。4.2 前端的确认与重试约定前端保留原输入按其clientRequestId查询送达状态其他回合仍在运行不能作为本消息已提交的证据确认中的行显示「正在确认」未知结果重试始终使用同一份请求和 ID不等待原回合结束已确认提交失败的行保留为可见失败项用户显式重试该失败任务时使用新请求 ID未确认的请求继续沿用原 ID前台和后台共用同一套确认逻辑恢复查询明确返回activeTurn: null时等待中的队列不能伪装为运行中的 agent。五、验证与使用故障注入与回归5.1 集成测试覆盖真实 HTTP Manager、remote stores 和执行租约集成测试见 queue-manager-integration.test.ts活动回合后排入两条消息模型按FIFO收到正文session 中每条输入只有一个 user item故障注入注入元数据写入、正文写入、commit 写入和响应丢失故障检查回滚、原地修复及并发幂等并发与生命周期检查旧 fencestale_turn_fence拒绝断言、跨线程隔离、自动重试、Stop 暂停、租约释放及显式继续、Runtime 重启后的 pending 恢复。5.2 前端与回归项前端检查确认失败、无关活动回合、pending/committed/terminal 回执、导航恢复及确认提示回归范围图片、Write/Design 上下文、Graph 引导、队列编辑、删除和顺序调整moveQueuedTurn/cancelQueuedTurn均以 3 次 revision CAS 重试实现见 turn-service-queue-operations.ts。5.3 线上恢复新构建生效后启动恢复会处理历史 pending 记录本地队列仍保留正文和请求 ID可按回执重新确认。不需要破坏性迁移或手工清空会话——恢复规则就是「正文存在则补齐提交正文不存在则回滚」。结语Kun 的排队输入交付链路把「入队」建模为受执行租约约束的两阶段提交事务pending 元数据、canonical user item、完成标记三段式落盘配合准确 turn ID 回滚、clientRequestId指纹幂等、250ms5s 退避重试与统一的在线/启动恢复规则从根上消除了「半提交排队记录」与「前端误确认送达」这两类典型故障。排查排队问题时优先确认三件事该 turn 是否仍带admissionPending标记、session 中是否已存在对应user_messageitem、以及queued-turns回执中该请求落在queuedTurns/pendingAdmissions/settledTurns的哪一档——三者即可定位其处于两阶段提交的哪个阶段。赞分享人工智能AI Agent自主智能体桌面应用MCP Clients【免费下载链接】KunLocal-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.项目地址https://gitcode.com/gh_mirrors/de/Kun点击查看免费下载相关推荐RustFS pool.bin 元数据升级与故障恢复实战指南V3 版本、两阶段提交与磁盘替换恢复RustFS pool.bin 元数据升级与故障恢复实战指南V3 版本、两阶段提交与磁盘替换恢复 pool.bin 是 RustFS 分布式对象存储的 集群级后端对象存储分布式存储Qwen3.5-122B-A10B-OptiQ-2bit常见问题解决安装、运行、性能调优FAQQwen3.5 122B A10B OptiQ 2bit常见问题解决安装、运行、性能调优FAQ Qwen3.5 122B A10B OptiQ 2bit是一款大模型模型量化本地部署多模态QwenCAP 中的消息幂等性交付保证、实现边界与两种可落地的幂等处理方案CAP 中的消息幂等性交付保证、实现边界与两种可落地的幂等处理方案 导读 本文以 CAP 官方文档《Idempotence》为主线系统梳理消息中间件中的三后端消息队列微服务消息路由上一篇LinkSwift深度解析九大网盘直链下载架构设计与实现原理下一篇Adobe-GenP 3.0二进制修补技术深度解析与Adobe CC激活架构设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考