Skip to content

fix(summary): mark refresh failed on terminal delivery - #37

Draft
lyingbug wants to merge 2 commits into
mainfrom
cursor/fix-summary-refresh-stuck-status-c9e2
Draft

fix(summary): mark refresh failed on terminal delivery#37
lyingbug wants to merge 2 commits into
mainfrom
cursor/fix-summary-refresh-stuck-status-c9e2

Conversation

@lyingbug

@lyingbug lyingbug commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Description

本分支基于 Tencent/WeKnora#2505 的 head,在其之上修复一个由该 PR 引入的状态卡死回归。若 Tencent#2505 尚未合并,建议将本次修复直接并入 Tencent#2505

问题

Tencent#2505 将摘要刷新分支中无条件summary_status = failed 写入:

logger.Warnf(ctx, "Summary refresh failed for knowledge %s: %v", payload.KnowledgeID, err)
_ = s.repo.UpdateKnowledgeColumn(ctx, payload.KnowledgeID, "summary_status", types.SummaryStatusFailed)

改成了裸的 return err,以便让 Asynq 的 MaxRetry(3) 生效。这个方向是对的,但 RegenerateKnowledgeSummary 有多条失败路径不会自己写任何状态

  • restoreSummaryRefreshTenantInfo 租户查询失败
  • GetKnowledgeByID / GetKnowledgeBaseByID 读取失败
  • kb.SummaryModelID == ""(排队期间 KB 配置被改)
  • ListChunksByKnowledgeID 读取失败
  • 设置 processingUpdateKnowledge 失败
  • 成功路径的 summarySourceChanged 返回查询错误

enqueueSummaryRefresh 在入队前已把状态写为 pendingRegenerateKnowledgeSummary 随后写 processing。上述任一路径连续失败 4 次后,状态永久停留在 pendingprocessing

前端把这两个状态都渲染为"正在生成摘要"的 loading 态(DocumentListView.vueDocumentCardView.vuedoc-content.vue 中的 isSummaryStatusInFlight),因此文档会无限显示"正在生成摘要",且 doc-content.vue 会持续轮询。

修改

新增 handleSummaryRefreshFailure,集中处理刷新失败的语义:

  • 非终端投递:保持 fix: retry document summaries before fallback Tencent/WeKnora#2505 的行为,返回错误让执行器重试,不写状态(applyRetryableSummaryFailureState 已负责写 pending)。
  • 终端投递:写入 summary_status = failed 后再返回错误。使用 UpdateKnowledgeColumn 而非整行写入,避免覆盖 RegenerateKnowledgeSummary 可能刚发布的首 chunk 兜底 description
  • ErrSummaryRefreshStale:仍然吞掉并返回 nil——更新的刷新任务拥有状态所有权。
  • errInsufficientSummaryContent:仍然吞掉——调用方已写入 failed

状态写入失败只记 warning,不掩盖原始生成错误。

Type of Change

  • 🐛 Bug fix

Related Issue

修复 Tencent/WeKnora#2505 引入的回归。

Checklist

  • Self-reviewed the code
  • Added/updated tests covering the change
  • go vet 与受影响包的测试全部通过(internal/application/serviceinternal/routerinternal/typesinternal/handlerinternal/middleware/...

新增 TestHandleSummaryRefreshFailure,覆盖:可重试投递不写状态、终端投递写 failed、包装后的错误仍能识别终端、stale 不写状态、insufficient-content 不额外写入、状态写入失败不掩盖原始错误。

注:go build ./... 在本环境因缺少 sqlite3.hsqlite-vec-go-bindings 的 cgo 依赖)而失败,与本次改动无关。

Open in Web Open in Cursor 

ttommybot and others added 2 commits August 3, 2026 19:02
PR Tencent#2505 replaced the unconditional summary_status=failed write in the
refresh branch with a bare error return so asynq could retry. Several
RegenerateKnowledgeSummary failure paths never persist a status of their
own (tenant lookup, KB lookup, unconfigured summary model, chunk
listing, freshness verification), so once the retry budget was spent the
row stayed in pending/processing and the frontend kept rendering
"generating summary" forever.

Route refresh failures through handleSummaryRefreshFailure, which keeps
the retry semantics for non-terminal deliveries and writes failed on the
last attempt. Stale and insufficient-content outcomes stay swallowed.

Co-authored-by: lyingbug <lyingbug@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants