Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
9ee8a523
Unverified
提交
9ee8a523
authored
1月 20, 2026
作者:
Will Chen
提交者:
GitHub
1月 20, 2026
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Prevent duplicate chat streams when one is already in progress (#2243)
上级
e655e5e4
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
26 行增加
和
0 行删除
+26
-0
useStreamChat.ts
src/hooks/useStreamChat.ts
+26
-0
没有找到文件。
src/hooks/useStreamChat.ts
浏览文件 @
9ee8a523
...
@@ -33,6 +33,10 @@ export function getRandomNumberId() {
...
@@ -33,6 +33,10 @@ export function getRandomNumberId() {
return
Math
.
floor
(
Math
.
random
()
*
1
_000_000_000_000_000
);
return
Math
.
floor
(
Math
.
random
()
*
1
_000_000_000_000_000
);
}
}
// Module-level set to track chatIds with active/pending streams
// This prevents race conditions when clicking rapidly before state updates
const
pendingStreamChatIds
=
new
Set
<
number
>
();
export
function
useStreamChat
({
export
function
useStreamChat
({
hasChatId
=
true
,
hasChatId
=
true
,
}:
{
hasChatId
?:
boolean
}
=
{})
{
}:
{
hasChatId
?:
boolean
}
=
{})
{
...
@@ -86,6 +90,19 @@ export function useStreamChat({
...
@@ -86,6 +90,19 @@ export function useStreamChat({
return
;
return
;
}
}
// Prevent duplicate streams - check module-level set to avoid race conditions
if
(
pendingStreamChatIds
.
has
(
chatId
))
{
console
.
warn
(
`[CHAT] Ignoring duplicate stream request for chat
${
chatId
}
- stream already in progress`
,
);
// Call onSettled to allow callers to clean up their local loading state
onSettled
?.();
return
;
}
// Mark this chat as having a pending stream
pendingStreamChatIds
.
add
(
chatId
);
setRecentStreamChatIds
((
prev
)
=>
{
setRecentStreamChatIds
((
prev
)
=>
{
const
next
=
new
Set
(
prev
);
const
next
=
new
Set
(
prev
);
next
.
add
(
chatId
);
next
.
add
(
chatId
);
...
@@ -127,6 +144,9 @@ export function useStreamChat({
...
@@ -127,6 +144,9 @@ export function useStreamChat({
});
});
},
},
onEnd
:
(
response
:
ChatResponseEnd
)
=>
{
onEnd
:
(
response
:
ChatResponseEnd
)
=>
{
// Remove from pending set now that stream is complete
pendingStreamChatIds
.
delete
(
chatId
);
if
(
response
.
updatedFiles
)
{
if
(
response
.
updatedFiles
)
{
setIsPreviewOpen
(
true
);
setIsPreviewOpen
(
true
);
refreshAppIframe
();
refreshAppIframe
();
...
@@ -159,6 +179,9 @@ export function useStreamChat({
...
@@ -159,6 +179,9 @@ export function useStreamChat({
onSettled
?.();
onSettled
?.();
},
},
onError
:
(
errorMessage
:
string
)
=>
{
onError
:
(
errorMessage
:
string
)
=>
{
// Remove from pending set now that stream ended with error
pendingStreamChatIds
.
delete
(
chatId
);
console
.
error
(
`[CHAT] Stream error for
${
chatId
}
:`
,
errorMessage
);
console
.
error
(
`[CHAT] Stream error for
${
chatId
}
:`
,
errorMessage
);
setErrorById
((
prev
)
=>
{
setErrorById
((
prev
)
=>
{
const
next
=
new
Map
(
prev
);
const
next
=
new
Map
(
prev
);
...
@@ -180,6 +203,9 @@ export function useStreamChat({
...
@@ -180,6 +203,9 @@ export function useStreamChat({
},
},
});
});
}
catch
(
error
)
{
}
catch
(
error
)
{
// Remove from pending set on exception
pendingStreamChatIds
.
delete
(
chatId
);
console
.
error
(
"[CHAT] Exception during streaming setup:"
,
error
);
console
.
error
(
"[CHAT] Exception during streaming setup:"
,
error
);
setIsStreamingById
((
prev
)
=>
{
setIsStreamingById
((
prev
)
=>
{
const
next
=
new
Map
(
prev
);
const
next
=
new
Map
(
prev
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论