Phase7
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 9s
CI / Go — node-agent tests (push) Failing after 8s
CI / Go — edge-gateway build (push) Successful in 14s

This commit is contained in:
smueller
2026-06-26 13:20:55 +02:00
parent 49a98ee31d
commit ab21f53cdd
86 changed files with 1207 additions and 63 deletions

View File

@@ -0,0 +1,48 @@
/** Credits charged for RAM usage: 1 credit per GB-minute (rounded up). */
export function calculateUsageCredits(ramMb: number, durationSeconds: number): number {
if (ramMb <= 0 || durationSeconds <= 0) {
return 0;
}
const gbMinutes = (ramMb / 1024) * (durationSeconds / 60);
return Math.max(1, Math.ceil(gbMinutes));
}
export function parseMinecraftListOutput(output: string): number {
const headerMatch = output.match(
/There are (\d+) of a max(?:imum)? of \d+ players? online/i,
);
if (headerMatch?.[1]) {
return Number.parseInt(headerMatch[1], 10);
}
const legacyMatch = output.match(/^(\d+) players? online/i);
if (legacyMatch?.[1]) {
return Number.parseInt(legacyMatch[1], 10);
}
return 0;
}
export interface IdlePolicy {
idleTimeoutMinutes: number;
idleGraceAfterStartMinutes: number;
idleCountdownSeconds: number;
}
export const DEFAULT_IDLE_POLICY: IdlePolicy = {
idleTimeoutMinutes: 15,
idleGraceAfterStartMinutes: 3,
idleCountdownSeconds: 120,
};
export function resolveIdlePolicy(plan?: Partial<IdlePolicy> | null): IdlePolicy {
return {
idleTimeoutMinutes: plan?.idleTimeoutMinutes ?? DEFAULT_IDLE_POLICY.idleTimeoutMinutes,
idleGraceAfterStartMinutes:
plan?.idleGraceAfterStartMinutes ?? DEFAULT_IDLE_POLICY.idleGraceAfterStartMinutes,
idleCountdownSeconds:
plan?.idleCountdownSeconds ?? DEFAULT_IDLE_POLICY.idleCountdownSeconds,
};
}

View File

@@ -0,0 +1,23 @@
import { describe, expect, it } from 'vitest';
import {
calculateUsageCredits,
parseMinecraftListOutput,
} from './index';
describe('metering', () => {
it('charges credits by RAM-GB-minutes', () => {
expect(calculateUsageCredits(1024, 60)).toBe(1);
expect(calculateUsageCredits(2048, 60)).toBe(2);
expect(calculateUsageCredits(512, 30)).toBe(1);
});
it('parses minecraft list command output', () => {
expect(
parseMinecraftListOutput('There are 2 of a max of 20 players online: Steve, Alex'),
).toBe(2);
expect(
parseMinecraftListOutput('There are 0 of a maximum of 10 players online:'),
).toBe(0);
});
});