init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1 @@
export declare const getAvailableMemoryFromCgroup: () => number | null;

View File

@@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAvailableMemoryFromCgroup = void 0;
const node_fs_1 = require("node:fs");
const getMaxMemoryFromCgroupV2 = () => {
try {
const data = (0, node_fs_1.readFileSync)('/sys/fs/cgroup/memory.max', 'utf-8');
// If --memory=[num] flag of "docker run" is not set, the value will be "max"
if (data.trim() === 'max') {
return Infinity;
}
return parseInt(data, 10);
}
catch (_a) {
return null;
}
};
const getAvailableMemoryFromCgroupV2 = () => {
try {
const data = (0, node_fs_1.readFileSync)('/sys/fs/cgroup/memory.current', 'utf-8');
return parseInt(data, 10);
}
catch (_a) {
return null;
}
};
const getMaxMemoryFromCgroupV1 = () => {
try {
const data = (0, node_fs_1.readFileSync)('/sys/fs/cgroup/memory/memory.limit_in_bytes', 'utf-8');
// If --memory=[num] flag of "docker run" is not set, the value will be "max"
if (data.trim() === 'max') {
return Infinity;
}
return parseInt(data, 10);
}
catch (_a) {
return null;
}
};
const getAvailableMemoryFromCgroupV1 = () => {
try {
const data = (0, node_fs_1.readFileSync)('/sys/fs/cgroup/memory/memory.usage_in_bytes', 'utf-8');
return parseInt(data, 10);
}
catch (_a) {
return null;
}
};
const getAvailableMemoryFromCgroup = () => {
const maxMemoryV2 = getMaxMemoryFromCgroupV2();
if (maxMemoryV2 !== null) {
const availableMemoryV2 = getAvailableMemoryFromCgroupV2();
if (availableMemoryV2 !== null) {
return maxMemoryV2 - availableMemoryV2;
}
}
const maxMemoryV1 = getMaxMemoryFromCgroupV1();
if (maxMemoryV1 !== null) {
const availableMemoryV1 = getAvailableMemoryFromCgroupV1();
if (availableMemoryV1 !== null) {
return maxMemoryV1 - availableMemoryV1;
}
}
return null;
};
exports.getAvailableMemoryFromCgroup = getAvailableMemoryFromCgroup;

View File

@@ -0,0 +1 @@
export declare const getMaxLambdaMemory: () => number | null;

View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMaxLambdaMemory = void 0;
const getMaxLambdaMemory = () => {
if (process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE) {
return (parseInt(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE, 10) * 1024 * 1024);
}
return null;
};
exports.getMaxLambdaMemory = getMaxLambdaMemory;

View File

@@ -0,0 +1 @@
export declare const getFreeMemoryFromProcMeminfo: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => number | null;

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFreeMemoryFromProcMeminfo = void 0;
const node_fs_1 = require("node:fs");
const logger_1 = require("../logger");
const getFreeMemoryFromProcMeminfo = (logLevel) => {
if (!(0, node_fs_1.existsSync)('/proc/meminfo')) {
return null;
}
try {
const data = (0, node_fs_1.readFileSync)('/proc/meminfo', 'utf-8');
// Split the file by lines and find the line with MemFree
const lines = data.split('\n');
const memAvailableLine = lines.find((line) => line.startsWith('MemAvailable'));
// If we couldn't find MemAvailable, return an error
if (!memAvailableLine) {
throw new Error('MemAvailable not found in /proc/meminfo');
}
// Extract the value and unit from the line
const matches = memAvailableLine.match(/(\d+)\s+(\w+)/);
if (!matches || matches.length !== 3) {
throw new Error('Failed to parse MemAvailable value');
}
const value = parseInt(matches[1], 10);
const unit = matches[2].toLowerCase();
// Convert the value to bytes based on its unit
switch (unit) {
case 'kb':
return value * 1024;
case 'mb':
return value * 1024 * 1024;
case 'gb':
return value * 1024 * 1024 * 1024;
default:
throw new Error(`Unknown unit: ${unit}`);
}
}
catch (err) {
logger_1.Log.warn({ indent: false, logLevel }, '/proc/meminfo exists but failed to get memory info. Error:');
logger_1.Log.warn({ indent: false, logLevel }, err);
return null;
}
};
exports.getFreeMemoryFromProcMeminfo = getFreeMemoryFromProcMeminfo;

View File

@@ -0,0 +1 @@
export declare const getAvailableMemory: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => number;

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAvailableMemory = void 0;
const node_os_1 = require("node:os");
const logger_1 = require("../logger");
const from_docker_cgroup_1 = require("./from-docker-cgroup");
const from_lambda_env_1 = require("./from-lambda-env");
const from_proc_meminfo_1 = require("./from-proc-meminfo");
const getAvailableMemory = (logLevel) => {
// If we are in Lambda, the most reliable way is to read the environment variable
// This is also pretty much free
const maxMemory = (0, from_lambda_env_1.getMaxLambdaMemory)();
if (maxMemory !== null) {
const nodeMemory = (0, node_os_1.freemem)();
return Math.min(nodeMemory, maxMemory);
}
// If cgroup memory data is available, we are in Docker, and we should respect it
const cgroupMemory = (0, from_docker_cgroup_1.getAvailableMemoryFromCgroup)();
if (cgroupMemory !== null) {
// There are 2 Docker memory configurations:
// 1. --memory=[num]
// 2. Global Docker memory limit
// If cgroup limit is higher than global memory, the global memory limit still applies
const nodeMemory = (0, node_os_1.freemem)();
const _procInfo = (0, from_proc_meminfo_1.getFreeMemoryFromProcMeminfo)(logLevel);
if (cgroupMemory > nodeMemory * 1.25 && Number.isFinite(cgroupMemory)) {
logger_1.Log.warn({ indent: false, logLevel }, 'Detected differing memory amounts:');
logger_1.Log.warn({ indent: false, logLevel }, `Memory reported by CGroup: ${(cgroupMemory / 1024 / 1024).toFixed(2)} MB`);
if (_procInfo !== null) {
logger_1.Log.warn({ indent: false, logLevel }, `Memory reported by /proc/meminfo: ${(_procInfo / 1024 / 1024).toFixed(2)} MB`);
}
logger_1.Log.warn({ indent: false, logLevel }, `Memory reported by Node: ${(nodeMemory / 1024 / 1024).toFixed(2)} MB`);
logger_1.Log.warn({ indent: false, logLevel }, 'You might have inadvertenly set the --memory flag of `docker run` to a value that is higher than the global Docker memory limit.');
logger_1.Log.warn({ indent: false, logLevel }, 'Using the lower amount of memory for calculation.');
}
return Math.min(nodeMemory, cgroupMemory);
}
const procInfo = (0, from_proc_meminfo_1.getFreeMemoryFromProcMeminfo)(logLevel);
if (procInfo !== null) {
return Math.min((0, node_os_1.freemem)(), procInfo);
}
return (0, node_os_1.freemem)();
};
exports.getAvailableMemory = getAvailableMemory;