Skip to content

Commit

Permalink
chore: watch request counts
Browse files Browse the repository at this point in the history
  • Loading branch information
hibig committed Dec 27, 2024
1 parent 393b8ce commit 79c879f
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 82 deletions.
1 change: 1 addition & 0 deletions config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export default defineConfig({
model: {},
initialState: {},
request: {},
keepalive: ['/playground/text-to-image'],
locale: {
antd: true,
baseNavigator: true,
Expand Down
17 changes: 17 additions & 0 deletions src/atoms/route-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { atom, getDefaultStore } from 'jotai';

export const routeCacheAtom = atom<any>(new Map());

export const setRouteCache = (key: string, value: any) => {
const store = getDefaultStore();
const cache = store.get(routeCacheAtom);
cache.set(key, value);
store.set(routeCacheAtom, cache);
};

export const deleteRouteCache = (key: string) => {
const store = getDefaultStore();
const cache = store.get(routeCacheAtom);
cache.delete(key);
store.set(routeCacheAtom, cache);
};
45 changes: 45 additions & 0 deletions src/atoms/watch-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
interface WatchRequest {
id: number;
token: any;
cancel: () => void;
}

declare global {
interface Window {
__GPUSTACK_WATCH_REQUEST_CLEAR__: {
watchIDValue: number;
requestList: WatchRequest[];
};
}
}

window.__GPUSTACK_WATCH_REQUEST_CLEAR__ = {
watchIDValue: 0,
requestList: []
};

export const updateWatchIDValue = () => {
window.__GPUSTACK_WATCH_REQUEST_CLEAR__.watchIDValue =
window.__GPUSTACK_WATCH_REQUEST_CLEAR__.watchIDValue + 1;
return window.__GPUSTACK_WATCH_REQUEST_CLEAR__.watchIDValue;
};

export const updateWatchRequest = (watchToken: WatchRequest) => {
window.__GPUSTACK_WATCH_REQUEST_CLEAR__.requestList.push(watchToken);
};

export const cancelWatchRequest = (n: number) => {
// cancel the before n requests
const requestList = window.__GPUSTACK_WATCH_REQUEST_CLEAR__.requestList;

for (let i = 0; i < n; i++) {
requestList[i]?.cancel?.();
}
window.__GPUSTACK_WATCH_REQUEST_CLEAR__.requestList = requestList.slice(n);
};

export const clearWatchRequestId = (id: number) => {
const requestList = window.__GPUSTACK_WATCH_REQUEST_CLEAR__.requestList;
const newRequestList = requestList.filter((item) => item.id !== id);
window.__GPUSTACK_WATCH_REQUEST_CLEAR__.requestList = newRequestList;
};
3 changes: 3 additions & 0 deletions src/config/route-cachekey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
playgroundTextToImage: '/playground/text-to-image'
};
40 changes: 29 additions & 11 deletions src/hooks/use-chunk-request.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import {
cancelWatchRequest,
clearWatchRequestId,
updateWatchIDValue,
updateWatchRequest
} from '@/atoms/watch-request';
import { WatchEventType } from '@/config';
import { request } from '@umijs/max';
import axios from 'axios';
Expand Down Expand Up @@ -106,6 +112,7 @@ export const sliceData = (data: string, loaded: number, loadedSize: any) => {
};

const useSetChunkRequest = () => {
const watchRequestList = window.__GPUSTACK_WATCH_REQUEST_CLEAR__.requestList;
const [requestReadyState, setRequestReadyState] = useState(3);
const axiosToken = useRef<any>(null);
const requestConfig = useRef<any>({});
Expand All @@ -124,17 +131,21 @@ const useSetChunkRequest = () => {
setRequestReadyState(3);
};

const resetResultSchema = (result: any[]) => {
// ============ handle list data ============
// return _.map(result, (data: any) => {
// if (data.type === WatchEventType.DELETE) {
// data.ids = _.map(data.items, (item: any) => item.id);
// }
// data.collection = data.items || [];
// return data;
// });
// ============ handle list data ============
const createAxiosToken = () => {
const { CancelToken } = axios;
const source = CancelToken.source();
const watchID = updateWatchIDValue();
return {
id: watchID,
token: source.token,
cancel() {
source.cancel();
clearWatchRequestId(watchID);
}
};
};

const resetResultSchema = (result: any[]) => {
return _.map(result, (data: any) => {
if (data.type === WatchEventType.DELETE) {
data.ids = data.data?.id ? [data.data.id] : [];
Expand All @@ -154,6 +165,12 @@ const useSetChunkRequest = () => {
reset();
axiosToken.current?.cancel?.();
axiosToken.current = createAxiosToken();

updateWatchRequest(axiosToken.current);
if (watchRequestList.length >= 4) {
cancelWatchRequest(watchRequestList.length - 4 || 1);
}

try {
const { request: requestData } = await request(url, {
params: {
Expand Down Expand Up @@ -243,7 +260,8 @@ const useSetChunkRequest = () => {
}, [requestReadyState]);

return {
setChunkRequest
setChunkRequest,
createAxiosToken
};
};

Expand Down
17 changes: 16 additions & 1 deletion src/layouts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-nocheck

import { routeCacheAtom } from '@/atoms/route-cache';
import { GPUStackVersionAtom, UpdateCheckAtom, userAtom } from '@/atoms/user';
import ShortCuts, {
modalConfig as ShortCutsConfig
Expand All @@ -14,6 +15,7 @@ import { ProLayout } from '@ant-design/pro-components';
import {
Link,
Outlet,
dropByCacheKey,
history,
matchRoutes,
useAppData,
Expand Down Expand Up @@ -94,6 +96,7 @@ export default (props: any) => {
const { initialize: initialize } = useOverlayScroller();
const { initialize: initializeMenu } = useOverlayScroller();
const [userInfo] = useAtom(userAtom);
const [routeCache] = useAtom(routeCacheAtom);
const [version] = useAtom(GPUStackVersionAtom);
const [updateCheck] = useAtom(UpdateCheckAtom);
const location = useLocation();
Expand All @@ -103,6 +106,8 @@ export default (props: any) => {
const [collapsed, setCollapsed] = useState(false);
const [collapseValue, setCollapseValue] = useState(false);

console.log('routeCache========', routeCache);

const initialInfo = (useModel && useModel('@@initialState')) || {
initialState: undefined,
loading: false,
Expand Down Expand Up @@ -135,6 +140,15 @@ export default (props: any) => {
});
};

const dropRouteCache = (pathname) => {
console.log('routeCache.keys()========', routeCache.keys());
for (let key of routeCache.keys()) {
if (key !== pathname && !routeCache.get(key)) {
dropByCacheKey(key);
routeCache.delete(key);
}
}
};
const runtimeConfig = {
...initialInfo,
logout: async (userInfo) => {
Expand All @@ -156,7 +170,7 @@ export default (props: any) => {
};

const newRoutes = filterRoutes(
clientRoutes.filter((route) => route.id === '@@/global-layout'),
clientRoutes.filter((route) => route.id === 'max-tabs'),
(route) => {
return (
(!!route.isLayout && route.id !== '@@/global-layout') ||
Expand Down Expand Up @@ -307,6 +321,7 @@ export default (props: any) => {
: '/playground';
history.push(pathname);
}
dropRouteCache(pathname);
}}
formatMessage={formatMessage}
menu={{
Expand Down
2 changes: 1 addition & 1 deletion src/locales/en-US/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ export default {
'vLLM: For non-GGUF format models, supports x86 Linux only.',
'models.form.backend.voxbox': 'vox-box: For non-GGUF format audio models.',
'models.form.search.gguftips':
'If using Mac or Windows as a worker, check GGUF (uncheck for audio models).',
'If using macOS or Windows as a worker, check GGUF (uncheck for audio models).',
'models.form.button.addlabel': 'Add Label'
};
2 changes: 1 addition & 1 deletion src/locales/zh-CN/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ export default {
'models.form.backend.vllm': 'vLLM: 用于非 GGUF 格式模型,仅支持 x86 Linux',
'models.form.backend.voxbox': 'vox-box: 用于非 GGUF 格式的音频模型',
'models.form.search.gguftips':
'当 Mac 或 Windows 作 worker 时勾选 GGUF(搜索音频模型时取消勾选)',
'当 macOS 或 Windows 作 worker 时勾选 GGUF(搜索音频模型时取消勾选)',
'models.form.button.addlabel': '添加标签'
};
62 changes: 37 additions & 25 deletions src/pages/llmodels/components/table-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ interface ModelsProps {
handleShowSizeChange?: (page: number, size: number) => void;
handlePageChange: (page: number, pageSize: number | undefined) => void;
handleDeleteSuccess: () => void;
onViewLogs: () => void;
onCancelViewLogs: () => void;
queryParams: {
page: number;
perPage: number;
Expand Down Expand Up @@ -106,6 +108,8 @@ const Models: React.FC<ModelsProps> = ({
handleSearch,
handlePageChange,
handleDeleteSuccess,
onViewLogs,
onCancelViewLogs,
dataSource,
gpuDeviceList,
workerList,
Expand Down Expand Up @@ -400,6 +404,7 @@ const Models: React.FC<ModelsProps> = ({

const handleLogModalCancel = useCallback(() => {
setOpenLogModal(false);
onCancelViewLogs();
}, []);

const handleDelete = async (row: any) => {
Expand Down Expand Up @@ -454,31 +459,38 @@ const Models: React.FC<ModelsProps> = ({
navigate(`/playground/chat?model=${row.name}`);
};

const handleViewLogs = async (row: any) => {
try {
setCurrentInstance({
url: `${MODEL_INSTANCE_API}/${row.id}/logs`,
status: row.state,
id: row.id,
modelId: row.model_id,
tail: InstanceRealLogStatus.includes(row.state) ? undefined : PageSize
});
setOpenLogModal(true);
} catch (error) {
console.log('error:', error);
}
};
const handleDeleteInstace = (row: any, list: ModelInstanceListItem[]) => {
modalRef.current.show({
content: 'models.instances',
okText: 'common.button.delrecreate',
operation: 'common.delete.single.confirm',
name: row.name,
async onOk() {
await deleteModelInstance(row.id);
const handleViewLogs = useCallback(
async (row: any) => {
try {
setCurrentInstance({
url: `${MODEL_INSTANCE_API}/${row.id}/logs`,
status: row.state,
id: row.id,
modelId: row.model_id,
tail: InstanceRealLogStatus.includes(row.state) ? undefined : PageSize
});
setOpenLogModal(true);
onViewLogs();
} catch (error) {
console.log('error:', error);
}
});
};
},
[onViewLogs]
);
const handleDeleteInstace = useCallback(
(row: any, list: ModelInstanceListItem[]) => {
modalRef.current.show({
content: 'models.instances',
okText: 'common.button.delrecreate',
operation: 'common.delete.single.confirm',
name: row.name,
async onOk() {
await deleteModelInstance(row.id);
}
});
},
[deleteModelInstance]
);

const getModelInstances = async (row: any) => {
const params = {
Expand Down Expand Up @@ -539,7 +551,7 @@ const Models: React.FC<ModelsProps> = ({
handleViewLogs(row);
}
},
[]
[handleViewLogs, handleDeleteInstace]
);

const renderModelTags = useCallback(
Expand Down
Loading

0 comments on commit 79c879f

Please sign in to comment.