优化: drainQueue并发互斥+deep watch指纹+前端打磨
This commit is contained in:
@@ -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)
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user