-
Notifications
You must be signed in to change notification settings - Fork 528
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): reorganizing all stats into a StatsManager
- Loading branch information
Showing
30 changed files
with
276 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const modulename = 'StatsManager'; | ||
import consoleFactory from '@extras/console'; | ||
import type TxAdmin from '@core/txAdmin.js'; | ||
import SvRuntimeStatsManager from './svRuntime'; | ||
import TxRuntimeStatsManager from './txRuntime'; | ||
import PlayerDropStatsManager from './playerDrop'; | ||
const console = consoleFactory(modulename); | ||
|
||
|
||
/** | ||
* Module responsible to collect statistics and data. | ||
* It is broken down into sub-modules for each specific area. | ||
* NOTE: yes, this could just have been an object, but who cares. | ||
*/ | ||
export default class StatsManager { | ||
public readonly svRuntime: SvRuntimeStatsManager; | ||
public readonly txRuntime: TxRuntimeStatsManager; | ||
public readonly playerDrop: PlayerDropStatsManager; | ||
|
||
constructor(txAdmin: TxAdmin) { | ||
this.svRuntime = new SvRuntimeStatsManager(txAdmin); | ||
this.txRuntime = new TxRuntimeStatsManager(txAdmin); | ||
this.playerDrop = new PlayerDropStatsManager(txAdmin); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
const modulename = 'PlayerDropStatsManager'; | ||
import consoleFactory from '@extras/console'; | ||
import type TxAdmin from '@core/txAdmin.js'; | ||
const console = consoleFactory(modulename); | ||
|
||
|
||
//Consts | ||
const STATS_DATA_FILE_VERSION = 1; | ||
const STATS_DATA_FILE_NAME = 'stats_playerDrop.json'; | ||
|
||
|
||
/** | ||
* FIXME: | ||
*/ | ||
export default class PlayerDropStatsManager { | ||
readonly #txAdmin: TxAdmin; | ||
private readonly statsDataPath: string; | ||
|
||
constructor(txAdmin: TxAdmin) { | ||
this.#txAdmin = txAdmin; | ||
this.statsDataPath = `${txAdmin.info.serverProfilePath}/data/${STATS_DATA_FILE_NAME}`; | ||
this.loadStatsHistory(); | ||
} | ||
|
||
|
||
/** | ||
* Loads the stats database/cache/history | ||
*/ | ||
async loadStatsHistory() { | ||
// try { | ||
// const rawFileData = await fsp.readFile(this.statsDataPath, 'utf8'); | ||
// const fileData = JSON.parse(rawFileData); | ||
// if (fileData?.version !== STATS_DATA_FILE_VERSION) throw new Error('invalid version'); | ||
// const statsData = SSFileSchema.parse(fileData); | ||
// this.lastPerfBoundaries = statsData.lastPerfBoundaries; | ||
// this.statsLog = statsData.log; | ||
// this.resetPerfState(); | ||
// console.verbose.debug(`Loaded ${this.statsLog.length} performance snapshots from cache`); | ||
// await optimizeStatsLog(this.statsLog); | ||
// } catch (error) { | ||
// if (error instanceof ZodError) { | ||
// console.warn(`Failed to load ${STATS_DATA_FILE_NAME} due to invalid data.`); | ||
// console.warn('Since this is not a critical file, it will be reset.'); | ||
// } else { | ||
// console.warn(`Failed to load ${STATS_DATA_FILE_NAME} with message: ${(error as Error).message}`); | ||
// console.warn('Since this is not a critical file, it will be reset.'); | ||
// } | ||
// } | ||
} | ||
|
||
|
||
/** | ||
* Saves the stats database/cache/history | ||
*/ | ||
async saveStatsHistory() { | ||
try { | ||
// await optimizeStatsLog(this.statsLog); | ||
// const savePerfData: SSFileType = { | ||
// version: STATS_DATA_FILE_VERSION, | ||
// lastPerfBoundaries: this.lastPerfBoundaries, | ||
// log: this.statsLog, | ||
// }; | ||
// await fsp.writeFile(this.statsDataPath, JSON.stringify(savePerfData)); | ||
} catch (error) { | ||
console.warn(`Failed to save ${STATS_DATA_FILE_NAME} with message: ${(error as Error).message}`); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* FIXME: | ||
*/ | ||
getServerPerfSummary() { | ||
//FIXME: | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { test, expect, suite, it } from 'vitest'; | ||
import { MultipleCounter, QuantileArray, TimeCounter } from './statsUtils'; | ||
|
||
|
||
suite('MultipleCounter', () => { | ||
it('should instantiate empty correctly', () => { | ||
const counter = new MultipleCounter(); | ||
expect(counter).toBeInstanceOf(MultipleCounter); | ||
expect(counter.toArray()).toEqual([]); | ||
expect(counter.toJSON()).toEqual({}); | ||
}); | ||
|
||
it('should instantiate locked if specified', () => { | ||
const lockedCounter = new MultipleCounter(undefined, true); | ||
expect(() => lockedCounter.count('a')).toThrowError('is locked'); | ||
expect(() => lockedCounter.clear()).toThrowError('is locked'); | ||
}); | ||
|
||
it('handle instantiation data error', () => { | ||
expect(() => new MultipleCounter(null as any)).toThrowError('must be an iterable'); | ||
expect(() => new MultipleCounter({ a: 'b' as any })).toThrowError('only integer'); | ||
}); | ||
|
||
const counterWithData = new MultipleCounter({ a: 1, b: 2 }); | ||
it('should instantiate with data correctly', () => { | ||
expect(counterWithData.toArray()).toEqual([['a', 1], ['b', 2]]); | ||
expect(counterWithData.toJSON()).toEqual({ a: 1, b: 2 }); | ||
}); | ||
it('should count and clear', () => { | ||
counterWithData.count('a'); | ||
expect(counterWithData.toJSON()).toEqual({ a: 2, b: 2 }); | ||
counterWithData.count('b'); | ||
counterWithData.count('c', 5); | ||
expect(counterWithData.toJSON()).toEqual({ a: 2, b: 3, c: 5}); | ||
counterWithData.clear(); | ||
expect(counterWithData.toJSON()).toEqual({}); | ||
}); | ||
}); | ||
|
||
|
||
test('QuantileArray', () => { | ||
const array = new QuantileArray(4, 2); | ||
array.count(0); | ||
expect(array.result()).toEqual({ notEnoughData: true }); | ||
array.count(0); | ||
array.count(0); | ||
array.count(0); | ||
expect(array.result()).toEqual({ | ||
count: 4, | ||
q5: 0, | ||
q25: 0, | ||
q50: 0, | ||
q75: 0, | ||
q95: 0, | ||
}); | ||
|
||
array.count(1); | ||
array.count(1); | ||
expect(array.result()).toEqual({ | ||
count: 4, | ||
q5: 0, | ||
q25: 0, | ||
q50: 0.5, | ||
q75: 1, | ||
q95: 1, | ||
}); | ||
|
||
array.clear(); | ||
expect(array.result()).toEqual({ notEnoughData: true }); | ||
}); | ||
|
||
|
||
test('TimeCounter', async () => { | ||
const counter = new TimeCounter(); | ||
await new Promise((resolve) => setTimeout(resolve, 150)); | ||
const duration = counter.stop(); | ||
|
||
// Check if the duration is a valid object | ||
expect(duration.seconds).toBeTypeOf('number'); | ||
expect(duration.milliseconds).toBeTypeOf('number'); | ||
expect(duration.nanoseconds).toBeTypeOf('number'); | ||
expect(counter.toJSON()).toEqual(duration); | ||
|
||
// Check if the duration is within the expected range | ||
const isCloseTo50ms = (x: number) => (x > 150 && x < 175); | ||
expect(duration.seconds * 1000).toSatisfy(isCloseTo50ms); | ||
expect(duration.milliseconds).toSatisfy(isCloseTo50ms); | ||
expect(duration.nanoseconds / 1_000_000).toSatisfy(isCloseTo50ms); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...onents/PerformanceCollector/perfParser.ts → ...ents/StatsManager/svRuntime/perfParser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.