mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
feat(ops): name 1536 MB as the supported memory floor
The getting-started requirements now say a host needs 3 GB of RAM, 4 GB recommended, and drop the advice to lower APP_MEMORY_LIMIT to 1g on a 2 GB host. The compose and .env example comments say the same. At boot the app reads its cgroup memory limit (v2, then v1) and logs one line when it is below MEMORY_FLOOR_MB. The support report adds the container limit and a note below the floor, and Admin > System status shows "below the supported floor" next to the existing low-heap flag. The app keeps running either way.
This commit is contained in:
1 parent
9941db1549
commit
07f9615dba
20 files changed
+313
-26
No files matched your search
@@ -44,12 +44,19 @@ vi.mock("@/lib/jobs/worker-status", () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
const heapMock = vi.hoisted(() => ({ mb: 792 }));
|
||||
const heapMock = vi.hoisted(() => ({
|
||||
mb: 792,
|
||||
container: 1536 as number | null,
|
||||
}));
|
||||
vi.mock("@/lib/support/heap-limit", async () => {
|
||||
const actual = await vi.importActual<
|
||||
typeof import("@/lib/support/heap-limit")
|
||||
>("@/lib/support/heap-limit");
|
||||
return { ...actual, heapLimitMb: () => heapMock.mb };
|
||||
return {
|
||||
...actual,
|
||||
heapLimitMb: () => heapMock.mb,
|
||||
containerMemoryLimitMb: () => heapMock.container,
|
||||
};
|
||||
});
|
||||
|
||||
const geoMock = vi.hoisted(() => ({
|
||||
@@ -200,12 +207,40 @@ describe("GET /api/admin/status (integration health summary)", () => {
|
||||
const low = (await (await GET()).json()) as {
|
||||
data: { memory: { heapLimitMb: number; low: boolean } };
|
||||
};
|
||||
expect(low.data.memory).toEqual({ heapLimitMb: 524, low: true });
|
||||
expect(low.data.memory).toMatchObject({ heapLimitMb: 524, low: true });
|
||||
heapMock.mb = 792;
|
||||
const enough = (await (await GET()).json()) as {
|
||||
data: { memory: { heapLimitMb: number; low: boolean } };
|
||||
};
|
||||
expect(enough.data.memory).toEqual({ heapLimitMb: 792, low: false });
|
||||
expect(enough.data.memory).toMatchObject({ heapLimitMb: 792, low: false });
|
||||
});
|
||||
|
||||
it("flags a container memory limit below the supported floor", async () => {
|
||||
type Memory = {
|
||||
containerLimitMb: number | null;
|
||||
floorMb: number;
|
||||
belowFloor: boolean;
|
||||
};
|
||||
heapMock.container = 1024;
|
||||
const below = (await (await GET()).json()) as { data: { memory: Memory } };
|
||||
expect(below.data.memory).toMatchObject({
|
||||
containerLimitMb: 1024,
|
||||
floorMb: 1536,
|
||||
belowFloor: true,
|
||||
});
|
||||
heapMock.container = 1536;
|
||||
const atFloor = (await (await GET()).json()) as {
|
||||
data: { memory: Memory };
|
||||
};
|
||||
expect(atFloor.data.memory.belowFloor).toBe(false);
|
||||
// No limit, or none readable: nothing to flag.
|
||||
heapMock.container = null;
|
||||
const none = (await (await GET()).json()) as { data: { memory: Memory } };
|
||||
expect(none.data.memory).toMatchObject({
|
||||
containerLimitMb: null,
|
||||
belowFloor: false,
|
||||
});
|
||||
heapMock.container = 1536;
|
||||
});
|
||||
|
||||
it("reports named failing queues through failingJobs only", async () => {
|
||||
|
||||
@@ -9,7 +9,13 @@ import {
|
||||
readFailingQueues,
|
||||
} from "@/lib/jobs/job-failures";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { heapLimitMb, isHeapLimitLow } from "@/lib/support/heap-limit";
|
||||
import {
|
||||
containerMemoryLimitMb,
|
||||
heapLimitMb,
|
||||
isBelowMemoryFloor,
|
||||
isHeapLimitLow,
|
||||
MEMORY_FLOOR_MB,
|
||||
} from "@/lib/support/heap-limit";
|
||||
import {
|
||||
geoLookupMode,
|
||||
geoProviderChosen,
|
||||
@@ -77,6 +83,8 @@ export const GET = apiHandler(async () => {
|
||||
// The process's heap ceiling, and whether it is the 1 GB-container size
|
||||
// that a long-used account can fill (`heap-limit.ts`).
|
||||
const heapLimit = heapLimitMb();
|
||||
// And the container's own limit against the supported floor.
|
||||
const containerLimit = containerMemoryLimitMb();
|
||||
|
||||
return apiSuccess({
|
||||
version: process.env.npm_package_version || "0.1.0",
|
||||
@@ -85,7 +93,13 @@ export const GET = apiHandler(async () => {
|
||||
buildTime: BUILD_TIME,
|
||||
startTime: START_TIME,
|
||||
database: "connected",
|
||||
memory: { heapLimitMb: heapLimit, low: isHeapLimitLow(heapLimit) },
|
||||
memory: {
|
||||
heapLimitMb: heapLimit,
|
||||
low: isHeapLimitLow(heapLimit),
|
||||
containerLimitMb: containerLimit,
|
||||
floorMb: MEMORY_FLOOR_MB,
|
||||
belowFloor: isBelowMemoryFloor(containerLimit),
|
||||
},
|
||||
worker: {
|
||||
running: workerStatus.running,
|
||||
startedAt: workerStatus.startedAt,
|
||||
|
||||
Reference in new issue
Block a user