Replace instance metrics with map lobby counts (Refs #139)
CI / checks (push) Successful in 4m55s

This commit is contained in:
2026-10-10 16:40:07 -04:00
parent 616b1937ed
commit aebfc7a783
10 changed files with 278 additions and 278 deletions
+48
View File
@@ -77,6 +77,7 @@ describe('historical metrics', () => {
});
expect(result.maps).toHaveLength(1);
expect(result.maps[0].matches).toEqual(result.matches);
expect(result.maps[0].running).toEqual({ average: null, peak: 0, capturedHours: 0 });
expect(result.registeredServerCount).toBe(0);
expect(result.servers).toEqual([]);
expect(result.scopeOptions.maps).not.toContainEqual({ game: 't5', map: 'Future Map' });
@@ -365,6 +366,8 @@ describe('historical metrics', () => {
expect(later.maps[0].availabilityUnknown * 3600).toBeCloseTo(90);
expect(later.pooledAvailability.value).toBeNull();
expect(initial.running).toEqual({ average: null, peak: 0, capturedHours: 0 });
expect(initial.maps[0].running).toEqual(initial.running);
expect(later.maps[0].running).toEqual({ average: 1, peak: 1, capturedHours: 90 / 3600 });
});
it('returns clipped interval boundaries and marks only partial UTC buckets', async () => {
@@ -597,6 +600,7 @@ describe('historical metrics', () => {
expect(result.running.average).toBeCloseTo(1.6);
expect(result.running.peak).toBe(3);
expect(result.running.capturedHours * 3600).toBeCloseTo(150);
expect(result.maps[0].running).toEqual(result.running);
expect(result.previous.running.average).toBe(4);
expect(result.previous.running.peak).toBe(4);
expect(result.previous.running.capturedHours * 3600).toBeCloseTo(90);
@@ -610,6 +614,50 @@ describe('historical metrics', () => {
);
});
it('counts concurrent lobbies per recorded game/map across reused names, clipped intervals and collection gaps', async () => {
const { recordMetrics, readMetrics } =
await import('../../src/lib/server/fleet/metrics.js');
const now = Date.UTC(2026, 0, 3, 12);
const since = now - 86400_000;
const one = { server: 'one', game: 't5', map: 'Moon', players: 0, capacity: null };
const two = { ...one, server: 'two', players: null };
const otherGame = { ...one, server: 't6-one', game: 't6' };
recordMetrics([one, two, otherGame], since - 30_000);
recordMetrics([{ ...one, server: 'three', players: 2 }], since + 15_000);
recordMetrics(
[
otherGame,
{ ...otherGame, server: 't6-two' },
{ ...otherGame, server: 't6-three' },
{ ...one, map: 'Kino Der Toten' }
],
since + 45_000
);
// Both lobby names are reused after the map was absent from a collection.
recordMetrics([one, { ...two, players: 0 }], now - 30_000);
// A snapshot with no elapsed time must not inflate the captured peak.
recordMetrics([one, two, { ...one, server: 'three' }], now);
const result = readMetrics(1, now);
const moon = result.maps.find((map) => map.game === 't5' && map.map === 'Moon')!;
expect(moon.running.average).toBeCloseTo(1.6);
expect(moon.running.peak).toBe(2);
expect(moon.running.capturedHours * 3600).toBeCloseTo(75);
expect(moon.idle * 3600).toBeCloseTo(75);
expect(moon.unknown * 3600).toBeCloseTo(15);
expect(moon.observed + moon.unknown).toBeCloseTo(
moon.running.average! * moon.running.capturedHours
);
const t6 = result.maps.find((map) => map.game === 't6')!;
expect(t6.running.average).toBeCloseTo(285 / 105);
expect(t6.running.peak).toBe(3);
expect(t6.running.capturedHours * 3600).toBeCloseTo(105);
const kino = result.maps.find((map) => map.map === 'Kino Der Toten')!;
expect(kino.running).toEqual({ average: 1, peak: 1, capturedHours: 90 / 3600 });
const scoped = readMetrics({ days: 1, game: 't5', map: 'Moon', timeZone: 'UTC' }, now);
expect(scoped.maps).toEqual([moon]);
expect(scoped.running).toEqual(moon.running);
});
it('matches current policy context through map aliases and prefers the durable owner', async () => {
const { recordMetrics, readMetrics } =
await import('../../src/lib/server/fleet/metrics.js');