Load current terminal session tail

This commit is contained in:
npc0-hue
2026-08-31 12:16:43 +08:00
parent 9691dbcb3d
commit bc927a5144
2 changed files with 38 additions and 2 deletions
@@ -102,6 +102,7 @@ export function ServerManagementTerminalDrawer({ open, serverId, serverName, plu
const initialHistoryPendingRef = useRef(false);
const liveSessionRef = useRef<string | null | undefined>(undefined);
const historyRequestRef = useRef(0);
const liveTailLoadedRef = useRef(new Map<string, number>());
const quickCommands = useMemo(() => terminalQuickCommandsForPlugin(pluginId), [pluginId]);
const supportsCommands = quickCommands.length > 0;
@@ -124,6 +125,22 @@ export function ServerManagementTerminalDrawer({ open, serverId, serverName, plu
});
}, []);
const loadLiveStreamTail = useCallback((stream: LogStreamResponse) => {
const latestSeq = Number(stream.latestSeq);
if (!Number.isFinite(latestSeq) || latestSeq <= 0) return;
const loadedThrough = liveTailLoadedRef.current.get(stream.id) ?? 0;
if (loadedThrough >= latestSeq) return;
liveTailLoadedRef.current.set(stream.id, latestSeq);
void platformApiClient.queryLogStream({ logStreamId: stream.id, afterSeq: Math.max(0, latestSeq - terminalHistoryWindow), limit: terminalHistoryWindow }).then((response) => {
if (!eventBelongsToLiveSession(stream.logSessionId, liveSessionRef.current)) return;
appendLines(response.entries.map((entry) => terminalLineFromLog({ ...stream, latestSeq: response.latestSeq }, entry)));
lockTerminalFollow();
}).catch((error) => {
if (!eventBelongsToLiveSession(stream.logSessionId, liveSessionRef.current)) return;
appendLines([terminalSystemLine("warn", `当前会话尾部日志读取失败,等待后续实时输出:${error instanceof Error ? error.message : "未知错误"}`, "SYSTEM", `tail-error-${stream.id}`, serverTimeRef.current)]);
});
}, [appendLines, lockTerminalFollow]);
useEffect(() => {
if (!open) return;
setStreams({ status: "loading" });
@@ -137,6 +154,7 @@ export function ServerManagementTerminalDrawer({ open, serverId, serverName, plu
setHistoryLines({ status: "idle" });
setSelectedHistoryStreamId("");
liveSessionRef.current = undefined;
liveTailLoadedRef.current.clear();
serverTimeRef.current = undefined;
historyRequestRef.current += 1;
initialHistoryPendingRef.current = true;
@@ -180,6 +198,7 @@ export function ServerManagementTerminalDrawer({ open, serverId, serverName, plu
if (!stream || !eventBelongsToLiveSession(stream.logSessionId, liveSessionRef.current)) return;
ready = true;
setStreams((current) => ({ status: "ready", data: mergeLogStreams(current.status === "ready" ? current.data : [], stream) }));
loadLiveStreamTail(stream);
});
events.addEventListener("ready", () => {
ready = true;
@@ -198,7 +217,7 @@ export function ServerManagementTerminalDrawer({ open, serverId, serverName, plu
if (!ready) setStreams({ status: "error", reason: "实时日志推送连接失败" });
};
return () => events.close();
}, [appendLines, lockTerminalFollow, open, serverId]);
}, [appendLines, loadLiveStreamTail, lockTerminalFollow, open, serverId]);
useEffect(() => {
if (!open || !historyOpen) return;