@typeberry/lib 0.6.0-40f6423 → 0.6.0-41cb030
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/jam/node/main.d.ts.map +1 -1
- package/packages/jam/node/main.js +2 -1
- package/packages/workers/api-node/host-environment.d.ts +19 -0
- package/packages/workers/api-node/host-environment.d.ts.map +1 -0
- package/packages/workers/api-node/host-environment.js +91 -0
- package/packages/workers/api-node/index.d.ts +1 -0
- package/packages/workers/api-node/index.d.ts.map +1 -1
- package/packages/workers/api-node/index.js +1 -0
- package/packages/workers/api-node/protocol.d.ts.map +1 -1
- package/packages/workers/api-node/protocol.js +2 -0
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,mBAAmB,CAAC;AAe/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAkC,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAKnF,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAWhE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,IAAI,CACxB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/node/main.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,mBAAmB,CAAC;AAe/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAkC,MAAM,EAAW,MAAM,kBAAkB,CAAC;AAKnF,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAWhE,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAsB,IAAI,CACxB,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAClC,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,CA0KlB"}
|
|
@@ -10,7 +10,7 @@ import { Listener } from "#@typeberry/listener";
|
|
|
10
10
|
import { tryAsU16, tryAsU32 } from "#@typeberry/numbers";
|
|
11
11
|
import { CURRENT_SUITE, CURRENT_VERSION, Result, version } from "#@typeberry/utils";
|
|
12
12
|
import { DirectPort, DirectWorkerConfig } from "#@typeberry/workers-api";
|
|
13
|
-
import { InMemWorkerConfig, LmdbWorkerConfig, ThreadPort } from "#@typeberry/workers-api-node";
|
|
13
|
+
import { InMemWorkerConfig, LmdbWorkerConfig, logHostEnvironment, ThreadPort } from "#@typeberry/workers-api-node";
|
|
14
14
|
import { getChainSpec, getDatabasePath, initializeDatabase, logger } from "./common.js";
|
|
15
15
|
import { initializeExtensions } from "./extensions.js";
|
|
16
16
|
import * as metrics from "./metrics.js";
|
|
@@ -24,6 +24,7 @@ export async function main(config, withRelPath, telemetry) {
|
|
|
24
24
|
logger.info `🫐 Typeberry ${version}. GP: ${CURRENT_VERSION} (${CURRENT_SUITE})`;
|
|
25
25
|
logger.info `🎸 Starting node: ${config.nodeName}.`;
|
|
26
26
|
logger.info `🖥️ PVM Backend: ${PvmBackend[config.pvmBackend]}.`;
|
|
27
|
+
logHostEnvironment(logger);
|
|
27
28
|
const chainSpec = getChainSpec(config.node.flavor);
|
|
28
29
|
const blake2b = await Blake2b.createHasher();
|
|
29
30
|
const nodeName = config.nodeName;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Logger } from "#@typeberry/logger";
|
|
2
|
+
/**
|
|
3
|
+
* Log details about the host the node is running on (cpu, memory, platform)
|
|
4
|
+
* and the memory limits that apply to the process.
|
|
5
|
+
*
|
|
6
|
+
* Call this once from the main thread. Worker threads share the same OS process,
|
|
7
|
+
* so the host/cgroup/ulimit values are identical for them; use `logHeapLimit`
|
|
8
|
+
* to log the per-isolate V8 heap limit instead.
|
|
9
|
+
*/
|
|
10
|
+
export declare function logHostEnvironment(logger: Logger): void;
|
|
11
|
+
/**
|
|
12
|
+
* Log just this isolate's V8 heap limit, labelled with the worker name.
|
|
13
|
+
*
|
|
14
|
+
* Worker threads get their own V8 isolate, so this can differ from the main
|
|
15
|
+
* thread. Everything else (cpu, host/cgroup/ulimit memory) is process-wide and
|
|
16
|
+
* already logged by `logHostEnvironment` on the main thread.
|
|
17
|
+
*/
|
|
18
|
+
export declare function logHeapLimit(logger: Logger, workerName: string): void;
|
|
19
|
+
//# sourceMappingURL=host-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-environment.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/host-environment.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAIhD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAoBvD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAErE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import v8 from "node:v8";
|
|
4
|
+
const toGiB = (bytes) => `${(bytes / 1024 ** 3).toFixed(1)} GiB`;
|
|
5
|
+
/**
|
|
6
|
+
* Log details about the host the node is running on (cpu, memory, platform)
|
|
7
|
+
* and the memory limits that apply to the process.
|
|
8
|
+
*
|
|
9
|
+
* Call this once from the main thread. Worker threads share the same OS process,
|
|
10
|
+
* so the host/cgroup/ulimit values are identical for them; use `logHeapLimit`
|
|
11
|
+
* to log the per-isolate V8 heap limit instead.
|
|
12
|
+
*/
|
|
13
|
+
export function logHostEnvironment(logger) {
|
|
14
|
+
const cpus = os.cpus();
|
|
15
|
+
const cpuModel = cpus[0]?.model ?? "unknown";
|
|
16
|
+
logger.info `💻 Platform: ${os.platform()}/${os.arch()}, Node ${process.version}.`;
|
|
17
|
+
logger.info `⚙️ CPU: ${cpuModel} (${cpus.length} cores, ${os.availableParallelism()} available).`;
|
|
18
|
+
logger.info `🧠 Memory: ${toGiB(os.freemem())} free / ${toGiB(os.totalmem())} total (host).`;
|
|
19
|
+
logger.info `📦 V8 heap limit: ${toGiB(v8.getHeapStatistics().heap_size_limit)}.`;
|
|
20
|
+
// On Linux the process can be capped well below host memory by the container
|
|
21
|
+
// runtime (cgroup) or an address-space ulimit. os.totalmem() reflects neither,
|
|
22
|
+
// so surface them explicitly to make OOMs diagnosable.
|
|
23
|
+
const cgroupLimit = readCgroupMemoryLimit();
|
|
24
|
+
if (cgroupLimit !== null) {
|
|
25
|
+
logger.info `🐳 cgroup memory limit: ${toGiB(cgroupLimit)}.`;
|
|
26
|
+
}
|
|
27
|
+
const addressSpaceLimit = readAddressSpaceLimit();
|
|
28
|
+
if (addressSpaceLimit !== null) {
|
|
29
|
+
logger.info `🚧 Address space limit (ulimit -v): ${toGiB(addressSpaceLimit)}.`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Log just this isolate's V8 heap limit, labelled with the worker name.
|
|
34
|
+
*
|
|
35
|
+
* Worker threads get their own V8 isolate, so this can differ from the main
|
|
36
|
+
* thread. Everything else (cpu, host/cgroup/ulimit memory) is process-wide and
|
|
37
|
+
* already logged by `logHostEnvironment` on the main thread.
|
|
38
|
+
*/
|
|
39
|
+
export function logHeapLimit(logger, workerName) {
|
|
40
|
+
logger.info `📦 V8 heap limit (${workerName}): ${toGiB(v8.getHeapStatistics().heap_size_limit)}.`;
|
|
41
|
+
}
|
|
42
|
+
/** Read the cgroup (v2, then v1) memory limit in bytes, or null if unlimited / unavailable. */
|
|
43
|
+
function readCgroupMemoryLimit() {
|
|
44
|
+
if (os.platform() !== "linux") {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
// cgroup v2 first, then the v1 fallback path.
|
|
48
|
+
for (const path of ["/sys/fs/cgroup/memory.max", "/sys/fs/cgroup/memory/memory.limit_in_bytes"]) {
|
|
49
|
+
try {
|
|
50
|
+
const raw = fs.readFileSync(path, "utf8").trim();
|
|
51
|
+
if (raw === "max") {
|
|
52
|
+
return null; // cgroup v2 sentinel for "no limit"
|
|
53
|
+
}
|
|
54
|
+
const value = Number(raw);
|
|
55
|
+
// cgroup v1 reports a value close to 2^63 when unbounded; treat anything at or
|
|
56
|
+
// above host memory as effectively no limit.
|
|
57
|
+
if (!Number.isFinite(value) || value <= 0 || value >= os.totalmem()) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// file missing or unreadable, fall through to the next candidate
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
/** Read the soft RLIMIT_AS (address space, i.e. `ulimit -v`) in bytes, or null if unlimited / unavailable. */
|
|
69
|
+
function readAddressSpaceLimit() {
|
|
70
|
+
if (os.platform() !== "linux") {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const limits = fs.readFileSync("/proc/self/limits", "utf8");
|
|
75
|
+
const line = limits.split("\n").find((l) => l.startsWith("Max address space"));
|
|
76
|
+
if (line === undefined) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// Columns are: name (multi-word), soft limit, hard limit, units.
|
|
80
|
+
const soft = line.slice("Max address space".length).trim().split(/\s+/)[0];
|
|
81
|
+
if (soft === undefined || soft === "unlimited") {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const value = Number(soft);
|
|
85
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// /proc not mounted or unreadable
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,WAAW,EAAc,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAI/C,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../../packages/workers/api-node/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,WAAW,EAAc,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAI/C,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMxE,yCAAyC;AACzC,oBAAY,qBAAqB;IAC/B,2DAA2D;IAC3D,iBAAiB,IAAI;IACrB,sCAAsC;IACtC,MAAM,IAAI;CACX;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC;AACF,yFAAyF;AACzF,MAAM,MAAM,kBAAkB,GAC1B,CAAC;IACC,wDAAwD;IACxD,IAAI,EAAE,qBAAqB,CAAC,iBAAiB,CAAC;CAC/C,GAAG,WAAW,CAAC,GAChB;IACE,8EAA8E;IAC9E,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC;IACnC,sCAAsC;IACtC,UAAU,EAAE,WAAW,CAAC;IACxB,4BAA4B;IAC5B,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAeN;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAC1C,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,EACjC,aAAa,EAAE,GAAG,EAClB,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAChC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,GAC5B;IACD,GAAG,EAAE,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,CAkCA;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAC/C,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,EACjC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC;IACT,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,EAAE,QAAQ,CAAC,OAAO,QAAQ,CAAC,CAAC;IACjC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACpC,CAAC,CAmDD"}
|
|
@@ -4,6 +4,7 @@ import { Level, Logger } from "#@typeberry/logger";
|
|
|
4
4
|
import { assertNever } from "#@typeberry/utils";
|
|
5
5
|
import { Channel } from "#@typeberry/workers-api";
|
|
6
6
|
import { LmdbWorkerConfig } from "./config.js";
|
|
7
|
+
import { logHeapLimit } from "./host-environment.js";
|
|
7
8
|
import { ThreadPort } from "./port.js";
|
|
8
9
|
const logger = Logger.new(import.meta.filename, "workers");
|
|
9
10
|
/** Type of the control plane message. */
|
|
@@ -65,6 +66,7 @@ export async function initWorker(protocol, paramsDecoder) {
|
|
|
65
66
|
// configure logger inside a worker thread
|
|
66
67
|
Logger.configureAll(process.env.JAM_LOG ?? "", Level.LOG);
|
|
67
68
|
logger.trace `Worker ${protocol.name} starting.`;
|
|
69
|
+
logHeapLimit(logger, protocol.name);
|
|
68
70
|
return new Promise((resolve, reject) => {
|
|
69
71
|
if (parentPort === null) {
|
|
70
72
|
throw new Error(`Unable to start ${protocol.name} worker. Not running in a worker thread!`);
|