fix: update instances with full data

main
jialin 1 year ago
parent db733ac9ce
commit 6185485c68

@ -47,6 +47,7 @@ const TableRow: React.FC<
const childrenDataRef = useRef<any[]>([]);
childrenDataRef.current = childrenData;
const axiosToken = useRef<any>(null);
const [updateChild, setUpdateChild] = useState(true);
const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({
dataList: childrenData,
@ -111,6 +112,9 @@ const TableRow: React.FC<
};
const filterUpdateChildrenHandler = () => {
if (!expanded) {
return;
}
const dataList = _.filter(tableContext.allChildren, (data: any) => {
return _.get(data, [childParentKey]) === _.get(record, [rowKey]);
});
@ -161,6 +165,8 @@ const TableRow: React.FC<
pollTimer.current = setInterval(() => {
handlePolling();
}, 1000);
} else {
handleLoadChildren();
}
};
@ -186,17 +192,13 @@ const TableRow: React.FC<
}
}, [expandedRowKeys]);
useEffect(() => {
if (expanded) {
handleLoadChildren();
}
}, [expanded]);
useEffect(() => {
const handleVisibilityChange = async () => {
if (document.visibilityState === 'hidden') {
cacheDataListRef.current = [];
// setChildrenData([]);
setUpdateChild(false);
} else {
setUpdateChild(true);
}
};
@ -208,15 +210,15 @@ const TableRow: React.FC<
}, []);
useEffect(() => {
if (!firstLoad && expanded) {
cacheDataListRef.current = childrenData;
if (updateChild) {
// for update watch data
filterUpdateChildrenHandler();
}
return () => {
chunkRequestRef.current?.current?.cancel?.();
cacheDataListRef.current = [];
};
}, [firstLoad, expanded, tableContext.allChildren]);
}, [updateChild, tableContext.allChildren]);
const renderRowPrefix = () => {
if (expandable && rowSelection) {
@ -296,7 +298,8 @@ const TableRow: React.FC<
renderChildrenData()
) : (
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
image={loading ? null : Empty.PRESENTED_IMAGE_SIMPLE}
description={loading ? null : undefined}
style={{
marginBlock: 0,
height: 54

@ -0,0 +1,65 @@
let bufferedData = '';
const findValidJSONStrings = (inputStr: string) => {
const validJSONStrings = [];
let startIndex = 0;
while (startIndex < inputStr.length) {
const openingBraceIndex = inputStr.indexOf('{', startIndex);
if (openingBraceIndex === -1) break; // No more opening braces
let closingBraceIndex = openingBraceIndex;
let braceCount = 0;
// find couple of braces
while (closingBraceIndex < inputStr.length) {
if (inputStr[closingBraceIndex] === '{') {
braceCount++;
} else if (inputStr[closingBraceIndex] === '}') {
braceCount--;
}
if (braceCount === 0) {
break;
}
closingBraceIndex++;
}
if (braceCount !== 0) {
// no matching closing brace
break;
}
const jsonString = inputStr.substring(
openingBraceIndex,
closingBraceIndex + 1
);
try {
const parsedData = JSON.parse(jsonString);
validJSONStrings.push(parsedData);
startIndex = closingBraceIndex + 1;
} catch (error) {
// mabye invalid JSON
break;
}
}
return {
parsedJSON: validJSONStrings,
remainingData: inputStr.slice(startIndex) // it is the not parsed data
};
};
// Web Worker
self.onmessage = function (event) {
bufferedData += event.data;
const { parsedJSON, remainingData } = findValidJSONStrings(bufferedData);
if (parsedJSON.length > 0) {
postMessage(parsedJSON);
}
// save the remaining data for the next message
bufferedData = remainingData;
};

@ -36,69 +36,6 @@ export const sliceJsonStr = (text: string) => {
return result;
};
export const parseJsonStr = (list: string[]) => {
return _.map(list, (str: string) => {
return JSON.parse(str);
});
};
const findMatchingClosingBracket = (inputStr: string, startIndex: number) => {
let count = 0;
for (let i = startIndex; i < inputStr.length; i += 1) {
if (inputStr[i] === '{') {
count += 1;
} else if (inputStr[i] === '}') {
count -= 1;
}
if (count === 0) {
return i;
}
}
return -1;
};
const findValidJSONStrings = (inputStr: string) => {
const validJSONStrings: any[] = [];
let startIndex = 0;
while (startIndex < inputStr.length) {
const openingBraceIndex = inputStr.indexOf('{', startIndex);
if (openingBraceIndex === -1) {
break; // No more opening braces
}
const closingBraceIndex = findMatchingClosingBracket(
inputStr,
openingBraceIndex
);
if (closingBraceIndex === -1) {
// If no matching closing brace, set startIndex to next character
startIndex = openingBraceIndex + 1;
} else {
const jsonString = inputStr.substring(
openingBraceIndex,
closingBraceIndex + 1
);
try {
const data = JSON.parse(jsonString);
validJSONStrings.push(data);
} catch (error) {
// Ignore invalid JSON
}
startIndex = closingBraceIndex + 1;
}
}
return validJSONStrings;
};
const parseData = (data: string) => {
const res = findValidJSONStrings(data);
return res;
};
export const createAxiosToken = () => {
const { CancelToken } = axios;
const source = CancelToken.source();
@ -123,7 +60,7 @@ const useSetChunkRequest = () => {
const particalConfig = { params: {}, contentType: 'json' };
const timer = useRef<any>(null);
const loadedSize = useRef(0);
const bufferedDataRef = useRef('');
const workerRef = useRef<any>(null);
const reset = () => {
loaded.current = 0;
@ -172,6 +109,23 @@ const useSetChunkRequest = () => {
cancelWatchRequest(watchRequestList.length - 4 || 1);
}
if (contentType === 'json') {
workerRef.current?.terminate();
workerRef.current = new Worker(
// @ts-ignore
new URL('./json-parser-worker.ts', import.meta.url)
);
workerRef.current.onmessage = function (event: any) {
const validJSON = event.data;
if (validJSON.length > 0) {
const result = resetResultSchema(validJSON);
handler(result);
}
};
}
try {
const { request: requestData } = await request(url, {
params: {
@ -188,38 +142,17 @@ const useSetChunkRequest = () => {
loaded.current = e.loaded || 0;
total.current = e.total || 0;
let currentRes = sliceData(response, e.loaded, loadedSize);
let result: any[] = [];
let cres = currentRes;
if (contentType === 'json') {
// Append the new data to the buffered data
bufferedDataRef.current += currentRes;
// Find valid JSON strings in the buffered data
let validJSON = findValidJSONStrings(bufferedDataRef.current);
if (validJSON.length > 0) {
result = resetResultSchema(validJSON);
// Calculate the position of the last complete JSON fragment, keeping the unfinished part
const lastValidJSON = validJSON[validJSON.length - 1];
const lastJSONIndex = bufferedDataRef.current.lastIndexOf(
JSON.stringify(lastValidJSON)
);
bufferedDataRef.current = bufferedDataRef.current.slice(
lastJSONIndex + JSON.stringify(lastValidJSON).length
);
}
handler(result);
let currentRes = sliceData(response, e.loaded, loadedSize);
workerRef.current.postMessage(currentRes);
} else {
handler(currentRes);
handler(response);
}
console.log('chunkrequest===', {
result,
result: response,
url,
params,
raw: cres
params
});
}
});

@ -9,7 +9,12 @@ import {
import _ from 'lodash';
import qs from 'query-string';
import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { MODELS_API, MODEL_INSTANCE_API, queryModelsList } from './apis';
import {
MODELS_API,
MODEL_INSTANCE_API,
queryModelsInstances,
queryModelsList
} from './apis';
import TableList from './components/table-list';
import { ListItem } from './config/types';
@ -81,39 +86,60 @@ const Models: React.FC = () => {
}
};
const fetchData = useCallback(async () => {
axiosToken?.cancel?.();
axiosToken = createAxiosToken();
setDataSource((pre) => {
pre.loading = true;
return { ...pre };
});
const getAllModelInstances = useCallback(async () => {
try {
instancesToken.current?.cancel?.();
instancesToken.current = createAxiosToken();
const params = {
..._.pickBy(queryParams, (val: any) => !!val)
page: 1,
perPage: 100
};
const res: any = await queryModelsList(params, {
cancelToken: axiosToken.token
});
setDataSource({
dataList: res.items || [],
loading: false,
loadend: true,
total: res.pagination.total,
deletedIds: []
const res: any = await queryModelsInstances(params, {
token: instancesToken.current.token
});
cacheInsDataListRef.current = res.items || [];
setModelInstances(res.items || []);
} catch (error) {
if (!isPageHidden.current) {
// ignore
}
}, []);
const fetchData = useCallback(
async (loadingVal?: boolean) => {
axiosToken?.cancel?.();
axiosToken = createAxiosToken();
setDataSource((pre) => {
pre.loading = loadingVal ?? true;
return { ...pre };
});
try {
const params = {
..._.pickBy(queryParams, (val: any) => !!val)
};
const res: any = await queryModelsList(params, {
cancelToken: axiosToken.token
});
setDataSource({
dataList: [],
dataList: res.items || [],
loading: false,
loadend: true,
total: dataSource.total,
total: res.pagination.total,
deletedIds: []
});
} catch (error) {
if (!isPageHidden.current) {
setDataSource({
dataList: [],
loading: false,
loadend: true,
total: dataSource.total,
deletedIds: []
});
}
}
}
}, [queryParams]);
},
[queryParams]
);
const handlePageChange = useCallback(
(page: number, pageSize: number | undefined) => {
@ -135,6 +161,7 @@ const Models: React.FC = () => {
const updateInstanceHandler = (list: any) => {
// filter the data
_.each(list, (data: any) => {
console.log('updateInstanceHandler====', data);
updateInstanceChunkedList(data);
});
};
@ -166,7 +193,7 @@ const Models: React.FC = () => {
} catch (error) {
// ignore
}
}, []);
}, [updateInstanceHandler]);
const handleOnViewLogs = useCallback(() => {
isPageHidden.current = true;
@ -174,13 +201,15 @@ const Models: React.FC = () => {
cacheDataListRef.current = [];
cacheInsDataListRef.current = [];
chunkInstanceRequedtRef.current?.current?.cancel?.();
instancesToken.current?.cancel?.();
}, []);
const handleOnCancelViewLogs = useCallback(async () => {
isPageHidden.current = false;
await getAllModelInstances();
await createModelsInstanceChunkRequest();
await createModelsChunkRequest();
fetchData();
fetchData(false);
}, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]);
const handleSearch = useCallback(async () => {
@ -232,19 +261,25 @@ const Models: React.FC = () => {
};
}, []);
useEffect(() => {
console.log('modelInstances====', modelInstances);
}, [modelInstances]);
useEffect(() => {
const handleVisibilityChange = async () => {
if (document.visibilityState === 'visible') {
isPageHidden.current = false;
await getAllModelInstances();
await createModelsInstanceChunkRequest();
await createModelsChunkRequest();
fetchData();
fetchData(false);
} else {
isPageHidden.current = true;
chunkRequedtRef.current?.current?.cancel?.();
cacheDataListRef.current = [];
cacheInsDataListRef.current = [];
chunkInstanceRequedtRef.current?.current?.cancel?.();
instancesToken.current?.cancel?.();
}
};

Loading…
Cancel
Save