import { getLogger } from "@scramjet/logger" ; import { IComponent , Logger , LoadCheckStat , LoadCheckConfig , LoadCheckContstants } from "@scramjet/types" ; import { defer } from "@scramjet/utility" ; import * as sysinfo from "systeminformation" ; import { DataStream , StringStream } from "scramjet" ; const MB = 1024 * 1024 ; /**
 * Provides methods to monitor resources usage and determine if machine is not overloaded.
 */ export class LoadCheck implements IComponent { type { LoadCheckConfig } config : LoadCheckConfig ; type { LoadCheckContstants } constants : LoadCheckContstants ; type { Logger } logger : Logger = getLogger ( this ) ; constructor ( config ) { this . config = config ; this . constants = { SAFE_OPERATION_LIMIT : this . config . safeOperationLimit * MB , MIN_INSTANCE_REQUIREMENTS : { freeMem : this . config . instanceRequirements . freeMem * MB , cpuLoad : this . config . instanceRequirements . cpuLoad , freeSpace : this . config . instanceRequirements . freeSpace * MB } } ; } /**
     * Gathers various resources usage and returns it as a  LoadCheckStat object.
     *
     *  returns { Promise < LoadCheckStat > } async getLoadCheck ( ) { const [ load , disksInfo , memInfo ] = await Promise . all ( [ sysinfo . currentLoad ( ) , sysinfo . fsSize ( ) , sysinfo . mem ( ) ] ) ; return { avgLoad : load . avgLoad , currentLoad : load . currentLoad || 85 , memFree : memInfo . free + Math . max ( 0 , memInfo . buffcache - this . constants . SAFE_OPERATION_LIMIT ) , memUsed : memInfo . used , fsSize : disksInfo } ; } returns { boolean } async overloaded ( ) { const check = await this . getLoadCheck ( ) ; this . logger . log ( check ) ; const conditionsMet = { cpu : check . avgLoad < 100 - this . constants . MIN_INSTANCE_REQUIREMENTS . cpuLoad , mem : check . memFree > this . constants . MIN_INSTANCE_REQUIREMENTS . freeMem , dsk : check . fsSize [ 0 ] . available > this . constants . MIN_INSTANCE_REQUIREMENTS . freeSpace } ; this . logger . log ( conditionsMet ) ; return ! ( conditionsMet . cpu && conditionsMet . mem && conditionsMet . dsk ) ; } returns { DataStream } getLoadCheckStream ( ) { const safeOperationsLimit = this . constants . SAFE_OPERATION_LIMIT ; return DataStream . from ( async function * ( ) { while ( true ) { const [ load , disksInfo , memInfo ] = await Promise . all ( [ sysinfo . currentLoad ( ) , sysinfo . fsSize ( ) , sysinfo . mem ( ) ] ) ; yield { avgLoad : load . avgLoad , currentLoad : load . currentLoad || 85 , memFree : memInfo . free + Math . max ( 0 , memInfo . buffcache - safeOperationsLimit ) , memUsed : memInfo . used , fsSize : disksInfo } ; await defer ( 1000 ) ; } } ) . JSONStringify ( ) ; } }