diff --git a/src/components/logs-viewer/parse-worker.ts b/src/components/logs-viewer/parse-worker.ts index f97a01eb..8ed82206 100644 --- a/src/components/logs-viewer/parse-worker.ts +++ b/src/components/logs-viewer/parse-worker.ts @@ -16,6 +16,7 @@ interface MessageProps { chunked?: boolean; progress?: number; percent?: number; + isDownloading?: boolean; } class AnsiParser { private cursorRow: number = 0; @@ -32,6 +33,7 @@ class AnsiParser { private chunked: boolean = true; // true: send data in chunks, false: send all data at once private reminder: string = ''; private lines: string[] = []; + isDownloading: boolean = false; private pageSize: number = 500; private colorMap = { '30': 'black', @@ -79,6 +81,10 @@ class AnsiParser { this.chunked = chunked ?? true; } + public setIsDownloading(isDownloading: boolean) { + this.isDownloading = isDownloading; + } + private setId() { this.uid += 1; return this.uid; @@ -168,14 +174,18 @@ class AnsiParser { const remainingText = input.slice(lastIndex); this.handleText(remainingText); - const result = this.screen.map((row, index) => ({ - content: removeBracketsFromLine(row.join('')), - uid: `${this.page}-${index}` - })); + // const result = this.screen.map((row, index) => ({ + // content: removeBracketsFromLine(row.join('')), + // uid: `${this.page}-${index}` + // })); + const result = this.screen.map((row, index) => + removeBracketsFromLine(row.join('')) + ); return { data: result, - lines: this.rawDataRows + lines: this.rawDataRows, + remainder: '' }; } @@ -219,12 +229,23 @@ class AnsiParser { this.isProcessing = true; while (this.taskQueue.length > 0) { - const input = this.reminder + this.taskQueue.shift(); + let input = ''; + + if (this.isDownloading) { + input = this.taskQueue.shift() || ''; + } else { + input = this.reminder + this.taskQueue.shift(); + } if (input) { try { - const result = this.processInputByLine(input); - this.reminder = result.remainder; + const result = this.isDownloading + ? this.processInput(input) + : this.processInputByLine(input); + if (!this.isDownloading) { + this.reminder = result.remainder; + } + if (this.chunked) { self.postMessage({ result: result.data, lines: result.lines }); } else if (!this.isComplete) { @@ -273,9 +294,11 @@ self.onmessage = function (event: MessageEvent) { page, isComplete = false, chunked = true, - percent = 0 + percent = 0, + isDownloading = false } = event.data; + parser.setIsDownloading(isDownloading); parser.setPage(page); parser.setIsCompelete(isComplete); parser.setChunked(chunked); diff --git a/src/components/logs-viewer/virtual-log-list.tsx b/src/components/logs-viewer/virtual-log-list.tsx index 5f947828..2d06c76b 100644 --- a/src/components/logs-viewer/virtual-log-list.tsx +++ b/src/components/logs-viewer/virtual-log-list.tsx @@ -4,7 +4,6 @@ import classNames from 'classnames'; import _ from 'lodash'; import React, { forwardRef, - memo, useCallback, useEffect, useImperativeHandle, @@ -25,10 +24,17 @@ interface LogsViewerProps { tail?: number; enableScorllLoad?: boolean; diffHeight?: number; + isDownloading?: boolean; } const LogsViewer: React.FC = forwardRef((props, ref) => { - const { diffHeight, url, tail: defaultTail, enableScorllLoad = true } = props; + const { + diffHeight, + url, + tail: defaultTail, + enableScorllLoad = true, + isDownloading + } = props; const { pageSize, page, setPage, setTotalPage, totalPage } = useLogsPagination(); const { setChunkFetch } = useSetChunkFetch(); @@ -64,9 +70,10 @@ const LogsViewer: React.FC = forwardRef((props, ref) => { }; const setCurrentData = (lines: string[]) => { + console.log('setCurrentData', lines); const dataList = lines.map((line, index) => { return { - content: removeBracketsFromLine(line), + content: line, uid: `${pageRef.current}-${index}` }; }); @@ -150,7 +157,8 @@ const LogsViewer: React.FC = forwardRef((props, ref) => { logParseWorker.current.postMessage({ inputStr: data, page: pageRef.current, - reset: clearScreen.current + reset: clearScreen.current, + isDownloading: isDownloading }); clearScreen.current = false; }; @@ -349,4 +357,4 @@ const LogsViewer: React.FC = forwardRef((props, ref) => { ); }); -export default memo(LogsViewer); +export default React.memo(LogsViewer); diff --git a/src/pages/llmodels/components/view-logs-modal.tsx b/src/pages/llmodels/components/view-logs-modal.tsx index f4ae394c..8174324f 100644 --- a/src/pages/llmodels/components/view-logs-modal.tsx +++ b/src/pages/llmodels/components/view-logs-modal.tsx @@ -4,7 +4,7 @@ import { useIntl } from '@umijs/max'; import { Modal } from 'antd'; import React, { useCallback, useEffect, useState } from 'react'; import { MODELS_API } from '../apis'; -import { InstanceRealtimeLogStatus } from '../config'; +import { InstanceRealtimeLogStatus, InstanceStatusMap } from '../config'; type ViewModalProps = { open: boolean; @@ -20,6 +20,7 @@ const ViewLogsModal: React.FC = (props) => { const { setChunkRequest } = useSetChunkRequest(); const { open, url, onCancel, tail } = props || {}; const [enableScorllLoad, setEnableScorllLoad] = useState(true); + const [instanceState, setInstanceState] = useState(''); const logsViewerRef = React.useRef(null); const requestRef = React.useRef(null); const contentRef = React.useRef(null); @@ -33,6 +34,7 @@ const ViewLogsModal: React.FC = (props) => { const data = list?.find((item: any) => item.data?.id === props.id); // state in InstanceRealtimeLogStatus will not enable scorll load, because it is in the trasisition state if (data) { + setInstanceState(data?.data?.state); setEnableScorllLoad( () => !InstanceRealtimeLogStatus.includes(data?.data?.state) ); @@ -111,6 +113,7 @@ const ViewLogsModal: React.FC = (props) => { url={url} tail={tail} enableScorllLoad={enableScorllLoad} + isDownloading={instanceState !== InstanceStatusMap.Downloading} params={{ follow: true }}