优化: drainQueue并发互斥+deep watch指纹+前端打磨

This commit is contained in:
lxy
2026-08-12 01:00:56 +08:00
parent 4ad78abad6
commit 5a4c821629
7 changed files with 36 additions and 37 deletions
+9
View File
@@ -267,14 +267,21 @@ async function editMessage(newMessage: string) {
* 卡死),也无任何用户反馈。现显式 catch:复位 streaming + 推错误气泡(后台会话不推,避免污染
* 当前视图)+ 回填失败消息到该会话队首并停 drain(不静默丢用户输入,保留剩余队列供手动重试/
* 编辑/取消)。成功路径不受影响——doSend 成功后端会再 emit AiCompleted 续 drain 链路。
*
* 并发互斥 — 每个会话维护 _draining 标志,防止 AiCompleted 并发触发两次 drainQueue
* 导致 splice 两条消息同时发送,顺序错乱。已在 drain 中则跳过,等待下一次 AiCompleted 续发。
*/
let _drainingConvs = new Set<string>()
export function drainQueue(convId?: string | null) {
if (state.queue.length === 0) return
// 找队首属于目标会话的消息;若穿越(非目标会话的项堵在队首)则跳过整条队列
const targetId = convId ?? state.activeConversationId
if (!targetId) return
// 并发互斥:该会话已在 drain 中则跳过,由下一轮 AiCompleted 续发
if (_drainingConvs.has(targetId)) return
const idx = state.queue.findIndex(q => q.conversationId === targetId)
if (idx === -1) return
_drainingConvs.add(targetId)
const next = state.queue.splice(idx, 1)[0]!
void (async () => {
try {
@@ -301,6 +308,8 @@ export function drainQueue(convId?: string | null) {
} as AiMessage)
}
console.error('[AI] drainQueue 续发失败:', e)
} finally {
_drainingConvs.delete(targetId)
}
})()
}