修复:更早历史的世代号在渲染期推进,切换项目的守卫不等 effect
- 换项目时 historyLoadTokenRef 与 projectPathRef 同一处推进,复位 effect 不再推进 - 旧读取在「切换提交完成、复位 effect 未跑」的窗口落地时立刻失效,不再合并条目或写游标 - ADR 第 1 条与决策记录说明推进时机与其安全性依据(该窗口内不会新起带旧游标的读取) Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
+9
-3
@@ -208,10 +208,18 @@ export function useDirectProjectChatController({
|
||||
*
|
||||
* 只比项目路径不够——A→B→A 之后在飞的旧 A 读取又落回同一个路径,会把新一代的加载态与游标
|
||||
* 一起改掉。世代号让任何非最新一次读取在落地时整段失效(不合并、不写游标、不关加载态)。
|
||||
*
|
||||
* 换项目的推进放在**渲染期**,与 `projectPathRef` 同一处:守卫要在切换提交之后立刻生效。
|
||||
* 放进下面的复位 effect 会晚一步——React 的 passive effect 走宏任务,promise 续体走微任务,
|
||||
* 旧读取可能在「提交完成、复位 effect 还没跑」的窗口里落地,那时世代号还是旧的,于是照常合并
|
||||
* 条目、写游标、关加载态(复位 effect 随后会清掉状态,但这仍是一次白跑的跨项目读取)。
|
||||
*/
|
||||
const historyLoadTokenRef = useRef(0);
|
||||
const projectPathRef = useRef<string | null>(projectPath);
|
||||
projectPathRef.current = projectPath;
|
||||
if (projectPathRef.current !== projectPath) {
|
||||
historyLoadTokenRef.current += 1;
|
||||
projectPathRef.current = projectPath;
|
||||
}
|
||||
const directTurnRunningRef = useRef(currentTurnRunning);
|
||||
directTurnRunningRef.current = currentTurnRunning;
|
||||
const commandInFlightRef = useRef(commandInFlight);
|
||||
@@ -227,8 +235,6 @@ export function useDirectProjectChatController({
|
||||
historyErrorRef.current = null;
|
||||
setHistoryError(null);
|
||||
historyOldestItemIdRef.current = null;
|
||||
// 换项目即换代:上一项目的在飞读取(停在旧世代号上)落地后整段失效。
|
||||
historyLoadTokenRef.current += 1;
|
||||
}, [projectPath]);
|
||||
|
||||
// 回合期间的平台会话保活由 Rust 持有:Direct 回合的占用登记时启动,占用释放(回合收口)即停止;
|
||||
|
||||
Reference in New Issue
Block a user