From 045328c1f63bf7f4c7cc80f1ef1dce305aae904c Mon Sep 17 00:00:00 2001 From: James Date: Wed, 26 Jun 2024 15:59:12 +0700 Subject: [PATCH 1/2] feat: add system resources --- cortex-js/package.json | 2 ++ cortex-js/src/app.module.ts | 2 ++ .../src/domain/models/resource.interface.ts | 15 ++++++++ .../controllers/events.controller.ts | 36 +++++++++++++++++++ .../resources-manager.module.ts | 8 +++++ .../resources-manager.service.ts | 24 +++++++++++++ 6 files changed, 87 insertions(+) create mode 100644 cortex-js/src/domain/models/resource.interface.ts create mode 100644 cortex-js/src/infrastructure/services/resources-manager/resources-manager.module.ts create mode 100644 cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts diff --git a/cortex-js/package.json b/cortex-js/package.json index 8f433f591..4a4db8592 100644 --- a/cortex-js/package.json +++ b/cortex-js/package.json @@ -53,6 +53,7 @@ "decompress": "^4.2.1", "js-yaml": "^4.1.0", "nest-commander": "^3.13.0", + "node-os-utils": "^1.3.7", "openai": "^4.50.0", "readline": "^1.3.0", "reflect-metadata": "^0.2.0", @@ -75,6 +76,7 @@ "@types/jest": "^29.5.2", "@types/js-yaml": "^4.0.9", "@types/node": "^20.12.9", + "@types/node-os-utils": "^1.3.4", "@types/supertest": "^6.0.2", "@types/update-notifier": "^6.0.8", "@types/uuid": "^9.0.8", diff --git a/cortex-js/src/app.module.ts b/cortex-js/src/app.module.ts index a343e4260..95b21bf49 100644 --- a/cortex-js/src/app.module.ts +++ b/cortex-js/src/app.module.ts @@ -31,6 +31,7 @@ import { ConfigsModule } from './usecases/configs/configs.module'; import { EnginesModule } from './usecases/engines/engines.module'; import { ConfigsController } from './infrastructure/controllers/configs.controller'; import { EnginesController } from './infrastructure/controllers/engines.controller'; +import { ResourceManagerModule } from './infrastructure/services/resources-manager/resources-manager.module'; @Module({ imports: [ @@ -58,6 +59,7 @@ import { EnginesController } from './infrastructure/controllers/engines.controll ExtensionsModule, ConfigsModule, EnginesModule, + ResourceManagerModule, ], controllers: [ AssistantsController, diff --git a/cortex-js/src/domain/models/resource.interface.ts b/cortex-js/src/domain/models/resource.interface.ts new file mode 100644 index 000000000..17be7d275 --- /dev/null +++ b/cortex-js/src/domain/models/resource.interface.ts @@ -0,0 +1,15 @@ +export interface ResourceEvent { + data: ResourceStatus; +} + +export interface ResourceStatus { + mem: UsedMemInfo; + cpu: { + usage: number; + }; +} + +export interface UsedMemInfo { + totalMemMb: number; + usedMemMb: number; +} diff --git a/cortex-js/src/infrastructure/controllers/events.controller.ts b/cortex-js/src/infrastructure/controllers/events.controller.ts index 123bb7374..ade7b1dab 100644 --- a/cortex-js/src/infrastructure/controllers/events.controller.ts +++ b/cortex-js/src/infrastructure/controllers/events.controller.ts @@ -16,14 +16,20 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { Observable, + catchError, combineLatest, + from, fromEvent, + interval, map, merge, of, startWith, + switchMap, throttleTime, } from 'rxjs'; +import { ResourcesManagerService } from '../services/resources-manager/resources-manager.service'; +import { ResourceEvent } from '@/domain/models/resource.interface'; @ApiTags('Events') @Controller('events') @@ -32,6 +38,7 @@ export class EventsController { private readonly downloadManagerService: DownloadManagerService, private readonly modelsUsecases: ModelsUsecases, private readonly eventEmitter: EventEmitter2, + private readonly resourcesManagerService: ResourcesManagerService, ) {} @ApiOperation({ @@ -83,4 +90,33 @@ export class EventsController { map(([status, event]) => ({ data: { status, event } })), ); } + + @ApiOperation({ + summary: 'Get resources status', + description: 'Retrieves the resources status of the system.', + }) + @Sse('resources') + resourcesEvent(): Observable { + const initialData$ = from( + this.resourcesManagerService.getResourceStatuses(), + ).pipe( + map((data) => ({ data: data })), + catchError((error) => { + console.error('Error fetching initial resource statuses', error); + return of(); // Ensure the stream is kept alive even if initial fetch fails + }), + ); + + const getResourceStatuses$ = interval(2000).pipe( + switchMap(() => this.resourcesManagerService.getResourceStatuses()), + map((data) => ({ data: data })), + catchError((error) => { + console.error('Error fetching resource statuses', error); + return of(); // Keep the stream alive on error + }), + ); + + // Merge the initial data with the interval updates + return merge(initialData$, getResourceStatuses$); + } } diff --git a/cortex-js/src/infrastructure/services/resources-manager/resources-manager.module.ts b/cortex-js/src/infrastructure/services/resources-manager/resources-manager.module.ts new file mode 100644 index 000000000..02c43c8bb --- /dev/null +++ b/cortex-js/src/infrastructure/services/resources-manager/resources-manager.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { ResourcesManagerService } from './resources-manager.service'; + +@Module({ + providers: [ResourcesManagerService], + exports: [ResourcesManagerService], +}) +export class ResourceManagerModule {} diff --git a/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts b/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts new file mode 100644 index 000000000..96e173ff3 --- /dev/null +++ b/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts @@ -0,0 +1,24 @@ +import { + ResourceStatus, + UsedMemInfo, +} from '@/domain/models/resource.interface'; +import { Injectable } from '@nestjs/common'; +import { cpu, mem } from 'node-os-utils'; + +@Injectable() +export class ResourcesManagerService { + async getResourceStatuses(): Promise { + const promises = [cpu.usage(), mem.used()]; + const results = await Promise.all(promises); + + const cpuUsage = results[0] as number; + const memInfo = results[1] as UsedMemInfo; + + return { + mem: memInfo, + cpu: { + usage: cpuUsage, + }, + }; + } +} From af0e3bd69b43b76f9193922195252d37bfd908f5 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 26 Jun 2024 22:53:56 +0700 Subject: [PATCH 2/2] using system information instead --- cortex-js/package.json | 2 -- cortex-js/src/domain/models/resource.interface.ts | 4 ++-- .../resources-manager/resources-manager.service.ts | 14 +++++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cortex-js/package.json b/cortex-js/package.json index 4a4db8592..8f433f591 100644 --- a/cortex-js/package.json +++ b/cortex-js/package.json @@ -53,7 +53,6 @@ "decompress": "^4.2.1", "js-yaml": "^4.1.0", "nest-commander": "^3.13.0", - "node-os-utils": "^1.3.7", "openai": "^4.50.0", "readline": "^1.3.0", "reflect-metadata": "^0.2.0", @@ -76,7 +75,6 @@ "@types/jest": "^29.5.2", "@types/js-yaml": "^4.0.9", "@types/node": "^20.12.9", - "@types/node-os-utils": "^1.3.4", "@types/supertest": "^6.0.2", "@types/update-notifier": "^6.0.8", "@types/uuid": "^9.0.8", diff --git a/cortex-js/src/domain/models/resource.interface.ts b/cortex-js/src/domain/models/resource.interface.ts index 17be7d275..72741d7f7 100644 --- a/cortex-js/src/domain/models/resource.interface.ts +++ b/cortex-js/src/domain/models/resource.interface.ts @@ -10,6 +10,6 @@ export interface ResourceStatus { } export interface UsedMemInfo { - totalMemMb: number; - usedMemMb: number; + total: number; + used: number; } diff --git a/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts b/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts index 96e173ff3..266015742 100644 --- a/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts +++ b/cortex-js/src/infrastructure/services/resources-manager/resources-manager.service.ts @@ -3,21 +3,25 @@ import { UsedMemInfo, } from '@/domain/models/resource.interface'; import { Injectable } from '@nestjs/common'; -import { cpu, mem } from 'node-os-utils'; +import systemInformation, { Systeminformation } from 'systeminformation'; @Injectable() export class ResourcesManagerService { async getResourceStatuses(): Promise { - const promises = [cpu.usage(), mem.used()]; + const promises = [systemInformation.currentLoad(), systemInformation.mem()]; const results = await Promise.all(promises); - const cpuUsage = results[0] as number; - const memInfo = results[1] as UsedMemInfo; + const cpuUsage = results[0] as Systeminformation.CurrentLoadData; + const memory = results[1] as Systeminformation.MemData; + const memInfo: UsedMemInfo = { + total: memory.total, + used: memory.used, + }; return { mem: memInfo, cpu: { - usage: cpuUsage, + usage: cpuUsage.avgLoad, }, }; }