chore: refactor watch system resource hook (#2048)
This commit is contained in:
parent
42da19a463
commit
63cffca51e
@ -1,3 +1,5 @@
|
|||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
@ -31,6 +33,11 @@ import { useMainViewState } from '@/hooks/useMainViewState'
|
|||||||
|
|
||||||
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
|
import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom'
|
||||||
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
||||||
|
import {
|
||||||
|
cpuUsageAtom,
|
||||||
|
gpusAtom,
|
||||||
|
ramUtilitizedAtom,
|
||||||
|
} from '@/helpers/atoms/SystemBar.atom'
|
||||||
|
|
||||||
const menuLinks = [
|
const menuLinks = [
|
||||||
{
|
{
|
||||||
@ -47,9 +54,12 @@ const menuLinks = [
|
|||||||
|
|
||||||
const BottomBar = () => {
|
const BottomBar = () => {
|
||||||
const { activeModel, stateModel } = useActiveModel()
|
const { activeModel, stateModel } = useActiveModel()
|
||||||
const { ram, cpu, gpus } = useGetSystemResources()
|
const { watch, stopWatching } = useGetSystemResources()
|
||||||
const progress = useAtomValue(appDownloadProgress)
|
const progress = useAtomValue(appDownloadProgress)
|
||||||
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
||||||
|
const gpus = useAtomValue(gpusAtom)
|
||||||
|
const cpu = useAtomValue(cpuUsageAtom)
|
||||||
|
const ramUtilitized = useAtomValue(ramUtilitizedAtom)
|
||||||
|
|
||||||
const { setMainViewState } = useMainViewState()
|
const { setMainViewState } = useMainViewState()
|
||||||
const downloadStates = useAtomValue(modelDownloadStateAtom)
|
const downloadStates = useAtomValue(modelDownloadStateAtom)
|
||||||
@ -67,6 +77,16 @@ const BottomBar = () => {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Watch for resource update
|
||||||
|
watch()
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
stopWatching()
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed bottom-0 left-16 z-20 flex h-12 w-[calc(100%-64px)] items-center justify-between border-t border-border bg-background/80 px-3">
|
<div className="fixed bottom-0 left-16 z-20 flex h-12 w-[calc(100%-64px)] items-center justify-between border-t border-border bg-background/80 px-3">
|
||||||
<div className="flex flex-shrink-0 items-center gap-x-2">
|
<div className="flex flex-shrink-0 items-center gap-x-2">
|
||||||
@ -127,7 +147,7 @@ const BottomBar = () => {
|
|||||||
<div className="flex items-center gap-x-3">
|
<div className="flex items-center gap-x-3">
|
||||||
<div className="flex items-center gap-x-2">
|
<div className="flex items-center gap-x-2">
|
||||||
<SystemItem name="CPU:" value={`${cpu}%`} />
|
<SystemItem name="CPU:" value={`${cpu}%`} />
|
||||||
<SystemItem name="Mem:" value={`${ram}%`} />
|
<SystemItem name="Mem:" value={`${ramUtilitized}%`} />
|
||||||
</div>
|
</div>
|
||||||
{gpus.length > 0 && (
|
{gpus.length > 0 && (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
import { Fragment, ReactNode } from 'react'
|
import { Fragment, ReactNode } from 'react'
|
||||||
|
|
||||||
import useAssistants from '@/hooks/useAssistants'
|
import useAssistants from '@/hooks/useAssistants'
|
||||||
|
import useGetSystemResources from '@/hooks/useGetSystemResources'
|
||||||
import useModels from '@/hooks/useModels'
|
import useModels from '@/hooks/useModels'
|
||||||
import useThreads from '@/hooks/useThreads'
|
import useThreads from '@/hooks/useThreads'
|
||||||
|
|
||||||
@ -14,6 +15,8 @@ const DataLoader: React.FC<Props> = ({ children }) => {
|
|||||||
useModels()
|
useModels()
|
||||||
useThreads()
|
useThreads()
|
||||||
useAssistants()
|
useAssistants()
|
||||||
|
useGetSystemResources()
|
||||||
|
console.debug('Load Data...')
|
||||||
|
|
||||||
return <Fragment>{children}</Fragment>
|
return <Fragment>{children}</Fragment>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,11 +282,9 @@ export default function EventHandler({ children }: { children: ReactNode }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('Registering events')
|
|
||||||
if (window.core?.events) {
|
if (window.core?.events) {
|
||||||
events.on(MessageEvent.OnMessageResponse, onNewMessageResponse)
|
events.on(MessageEvent.OnMessageResponse, onNewMessageResponse)
|
||||||
events.on(MessageEvent.OnMessageUpdate, onMessageResponseUpdate)
|
events.on(MessageEvent.OnMessageUpdate, onMessageResponseUpdate)
|
||||||
|
|
||||||
events.on(ModelEvent.OnModelReady, onModelReady)
|
events.on(ModelEvent.OnModelReady, onModelReady)
|
||||||
events.on(ModelEvent.OnModelFail, onModelInitFailed)
|
events.on(ModelEvent.OnModelFail, onModelInitFailed)
|
||||||
events.on(ModelEvent.OnModelStopped, onModelStopped)
|
events.on(ModelEvent.OnModelStopped, onModelStopped)
|
||||||
|
|||||||
@ -41,14 +41,14 @@ const EventListenerWrapper = ({ children }: PropsWithChildren) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('EventListenerWrapper: registering event listeners...')
|
console.debug('EventListenerWrapper: registering event listeners...')
|
||||||
|
|
||||||
events.on(DownloadEvent.onFileDownloadUpdate, onFileDownloadUpdate)
|
events.on(DownloadEvent.onFileDownloadUpdate, onFileDownloadUpdate)
|
||||||
events.on(DownloadEvent.onFileDownloadError, onFileDownloadError)
|
events.on(DownloadEvent.onFileDownloadError, onFileDownloadError)
|
||||||
events.on(DownloadEvent.onFileDownloadSuccess, onFileDownloadSuccess)
|
events.on(DownloadEvent.onFileDownloadSuccess, onFileDownloadSuccess)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
console.log('EventListenerWrapper: unregistering event listeners...')
|
console.debug('EventListenerWrapper: unregistering event listeners...')
|
||||||
events.off(DownloadEvent.onFileDownloadUpdate, onFileDownloadUpdate)
|
events.off(DownloadEvent.onFileDownloadUpdate, onFileDownloadUpdate)
|
||||||
events.off(DownloadEvent.onFileDownloadError, onFileDownloadError)
|
events.off(DownloadEvent.onFileDownloadError, onFileDownloadError)
|
||||||
events.off(DownloadEvent.onFileDownloadSuccess, onFileDownloadSuccess)
|
events.off(DownloadEvent.onFileDownloadSuccess, onFileDownloadSuccess)
|
||||||
|
|||||||
@ -2,8 +2,10 @@ import { atom } from 'jotai'
|
|||||||
|
|
||||||
export const totalRamAtom = atom<number>(0)
|
export const totalRamAtom = atom<number>(0)
|
||||||
export const usedRamAtom = atom<number>(0)
|
export const usedRamAtom = atom<number>(0)
|
||||||
export const availableRamAtom = atom<number>(0)
|
|
||||||
|
|
||||||
export const cpuUsageAtom = atom<number>(0)
|
export const cpuUsageAtom = atom<number>(0)
|
||||||
|
export const ramUtilitizedAtom = atom<number>(0)
|
||||||
|
|
||||||
|
export const gpusAtom = atom<Record<string, never>[]>([])
|
||||||
|
|
||||||
export const nvidiaTotalVramAtom = atom<number>(0)
|
export const nvidiaTotalVramAtom = atom<number>(0)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { ExtensionTypeEnum, MonitoringExtension } from '@janhq/core'
|
import { ExtensionTypeEnum, MonitoringExtension } from '@janhq/core'
|
||||||
|
|
||||||
@ -6,25 +6,27 @@ import { useSetAtom } from 'jotai'
|
|||||||
|
|
||||||
import { extensionManager } from '@/extension/ExtensionManager'
|
import { extensionManager } from '@/extension/ExtensionManager'
|
||||||
import {
|
import {
|
||||||
availableRamAtom,
|
|
||||||
cpuUsageAtom,
|
cpuUsageAtom,
|
||||||
totalRamAtom,
|
totalRamAtom,
|
||||||
usedRamAtom,
|
usedRamAtom,
|
||||||
nvidiaTotalVramAtom,
|
nvidiaTotalVramAtom,
|
||||||
|
gpusAtom,
|
||||||
|
ramUtilitizedAtom,
|
||||||
} from '@/helpers/atoms/SystemBar.atom'
|
} from '@/helpers/atoms/SystemBar.atom'
|
||||||
|
|
||||||
export default function useGetSystemResources() {
|
export default function useGetSystemResources() {
|
||||||
const [ram, setRam] = useState<number>(0)
|
const [intervalId, setIntervalId] = useState<
|
||||||
const [cpu, setCPU] = useState<number>(0)
|
NodeJS.Timeout | number | undefined
|
||||||
|
>(undefined)
|
||||||
|
|
||||||
const [gpus, setGPUs] = useState<Record<string, never>[]>([])
|
|
||||||
const setTotalRam = useSetAtom(totalRamAtom)
|
const setTotalRam = useSetAtom(totalRamAtom)
|
||||||
|
const setGpus = useSetAtom(gpusAtom)
|
||||||
const setUsedRam = useSetAtom(usedRamAtom)
|
const setUsedRam = useSetAtom(usedRamAtom)
|
||||||
const setAvailableRam = useSetAtom(availableRamAtom)
|
|
||||||
const setCpuUsage = useSetAtom(cpuUsageAtom)
|
const setCpuUsage = useSetAtom(cpuUsageAtom)
|
||||||
const setTotalNvidiaVram = useSetAtom(nvidiaTotalVramAtom)
|
const setTotalNvidiaVram = useSetAtom(nvidiaTotalVramAtom)
|
||||||
|
const setRamUtilitized = useSetAtom(ramUtilitizedAtom)
|
||||||
|
|
||||||
const getSystemResources = async () => {
|
const getSystemResources = useCallback(async () => {
|
||||||
if (
|
if (
|
||||||
!extensionManager.get<MonitoringExtension>(
|
!extensionManager.get<MonitoringExtension>(
|
||||||
ExtensionTypeEnum.SystemMonitoring
|
ExtensionTypeEnum.SystemMonitoring
|
||||||
@ -38,23 +40,20 @@ export default function useGetSystemResources() {
|
|||||||
const resourceInfor = await monitoring?.getResourcesInfo()
|
const resourceInfor = await monitoring?.getResourcesInfo()
|
||||||
const currentLoadInfor = await monitoring?.getCurrentLoad()
|
const currentLoadInfor = await monitoring?.getCurrentLoad()
|
||||||
|
|
||||||
const ram =
|
|
||||||
(resourceInfor?.mem?.usedMemory ?? 0) /
|
|
||||||
(resourceInfor?.mem?.totalMemory ?? 1)
|
|
||||||
if (resourceInfor?.mem?.usedMemory) setUsedRam(resourceInfor.mem.usedMemory)
|
if (resourceInfor?.mem?.usedMemory) setUsedRam(resourceInfor.mem.usedMemory)
|
||||||
if (resourceInfor?.mem?.totalMemory)
|
if (resourceInfor?.mem?.totalMemory)
|
||||||
setTotalRam(resourceInfor.mem.totalMemory)
|
setTotalRam(resourceInfor.mem.totalMemory)
|
||||||
|
|
||||||
setRam(Math.round(ram * 100))
|
const ramUtilitized =
|
||||||
if (resourceInfor.mem.totalMemory && resourceInfor.mem.usedMemory)
|
((resourceInfor?.mem?.usedMemory ?? 0) /
|
||||||
setAvailableRam(
|
(resourceInfor?.mem?.totalMemory ?? 1)) *
|
||||||
resourceInfor.mem.totalMemory - resourceInfor.mem.usedMemory
|
100
|
||||||
)
|
setRamUtilitized(Math.round(ramUtilitized))
|
||||||
setCPU(Math.round(currentLoadInfor?.cpu?.usage ?? 0))
|
|
||||||
setCpuUsage(Math.round(currentLoadInfor?.cpu?.usage ?? 0))
|
setCpuUsage(Math.round(currentLoadInfor?.cpu?.usage ?? 0))
|
||||||
|
|
||||||
const gpus = currentLoadInfor?.gpu ?? []
|
const gpus = currentLoadInfor?.gpu ?? []
|
||||||
setGPUs(gpus)
|
setGpus(gpus)
|
||||||
|
|
||||||
let totalNvidiaVram = 0
|
let totalNvidiaVram = 0
|
||||||
if (gpus.length > 0) {
|
if (gpus.length > 0) {
|
||||||
@ -65,27 +64,49 @@ export default function useGetSystemResources() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
setTotalNvidiaVram(totalNvidiaVram)
|
setTotalNvidiaVram(totalNvidiaVram)
|
||||||
}
|
}, [
|
||||||
|
setUsedRam,
|
||||||
|
setTotalRam,
|
||||||
|
setRamUtilitized,
|
||||||
|
setCpuUsage,
|
||||||
|
setGpus,
|
||||||
|
setTotalNvidiaVram,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
const watch = () => {
|
||||||
getSystemResources()
|
getSystemResources()
|
||||||
|
|
||||||
// Fetch interval - every 2s
|
// Fetch interval - every 2s
|
||||||
// TODO: Will we really need this?
|
const itv = setInterval(() => {
|
||||||
// There is a possibility that this will be removed and replaced by the process event hook?
|
|
||||||
const intervalId = setInterval(() => {
|
|
||||||
getSystemResources()
|
getSystemResources()
|
||||||
}, 5000)
|
}, 2000)
|
||||||
|
setIntervalId(itv)
|
||||||
|
}
|
||||||
|
const stopWatching = useCallback(() => {
|
||||||
|
if (intervalId) clearInterval(intervalId)
|
||||||
|
}, [intervalId])
|
||||||
|
|
||||||
// clean up interval
|
useEffect(() => {
|
||||||
return () => clearInterval(intervalId)
|
getSystemResources()
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// Component did unmount
|
||||||
}, [])
|
// Stop watching if any
|
||||||
|
return () => {
|
||||||
|
stopWatching()
|
||||||
|
}
|
||||||
|
}, [getSystemResources, stopWatching])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalRamAtom,
|
/**
|
||||||
ram,
|
* Fetch resource informations once
|
||||||
cpu,
|
*/
|
||||||
gpus,
|
getSystemResources,
|
||||||
|
/**
|
||||||
|
* Fetch & watch for resource update
|
||||||
|
*/
|
||||||
|
watch,
|
||||||
|
/**
|
||||||
|
* Stop watching
|
||||||
|
*/
|
||||||
|
stopWatching,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user