@nxtedition/lib 27.0.0-alpha.0 → 27.0.0
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/app.js +38 -7
- package/couch.d.ts +1 -0
- package/numa.js +22 -13
- package/package.json +2 -2
package/app.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
1
2
|
import * as inspector from 'node:inspector'
|
|
2
3
|
import fs from 'node:fs'
|
|
3
4
|
import os from 'node:os'
|
|
@@ -7,9 +8,9 @@ import assert from 'node:assert'
|
|
|
7
8
|
import cluster from 'node:cluster'
|
|
8
9
|
import stream from 'node:stream'
|
|
9
10
|
import { Buffer } from 'node:buffer'
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
11
|
+
import v8 from 'node:v8'
|
|
12
|
+
import { isPrimary } from 'node:cluster'
|
|
13
|
+
import { monitorEventLoopDelay } from 'node:perf_hooks'
|
|
13
14
|
import {
|
|
14
15
|
isMainThread,
|
|
15
16
|
parentPort,
|
|
@@ -17,13 +18,16 @@ import {
|
|
|
17
18
|
BroadcastChannel,
|
|
18
19
|
resourceLimits,
|
|
19
20
|
} from 'node:worker_threads'
|
|
21
|
+
|
|
22
|
+
import { getDockerSecretsSync } from './docker-secrets.js'
|
|
23
|
+
import { getUTCRangeForLocalTime } from './time.js'
|
|
24
|
+
import fp from 'lodash/fp.js'
|
|
20
25
|
import deepstream from '@nxtedition/deepstream.io-client-js'
|
|
21
26
|
import { createLogger } from './logger.js'
|
|
22
27
|
import nconf from 'nconf'
|
|
23
28
|
import { makeCouch } from './couch.js'
|
|
24
29
|
import { makeTemplateCompiler } from '@nxtedition/template'
|
|
25
30
|
import { makeDeepstream } from './deepstream.js'
|
|
26
|
-
import v8 from 'v8'
|
|
27
31
|
import * as rxjs from 'rxjs'
|
|
28
32
|
import rx from 'rxjs/operators'
|
|
29
33
|
import { performance } from 'perf_hooks'
|
|
@@ -31,15 +35,18 @@ import hashString from './hash.js'
|
|
|
31
35
|
import { makeTrace } from './trace.js'
|
|
32
36
|
import { compose, createServer } from './http.js'
|
|
33
37
|
import { json } from 'node:stream/consumers'
|
|
34
|
-
import { monitorEventLoopDelay } from 'node:perf_hooks'
|
|
35
38
|
import xuid from 'xuid'
|
|
36
39
|
import { isTimeBetween } from './time.js'
|
|
37
40
|
import makeUnderPressure from './under-pressure.js'
|
|
38
|
-
import { isPrimary } from 'node:cluster'
|
|
39
41
|
import { nice } from '@nxtedition/sched'
|
|
40
42
|
import { setAffinity } from './numa.js'
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
/**
|
|
45
|
+
* @param {object} appConfig
|
|
46
|
+
* @param {object} [meta]
|
|
47
|
+
* @returns {object}
|
|
48
|
+
*/
|
|
49
|
+
export function makeApp(appConfig, onTerminateOrMeta, metaOrNull) {
|
|
43
50
|
let ds
|
|
44
51
|
let nxt
|
|
45
52
|
let couch
|
|
@@ -49,6 +56,27 @@ export function makeApp(appConfig, onTerminate) {
|
|
|
49
56
|
let logger
|
|
50
57
|
let trace
|
|
51
58
|
|
|
59
|
+
let onTerminate
|
|
60
|
+
let meta
|
|
61
|
+
|
|
62
|
+
if (typeof onTerminateOrMeta === 'function') {
|
|
63
|
+
meta = metaOrNull
|
|
64
|
+
} else {
|
|
65
|
+
meta = onTerminateOrMeta ?? metaOrNull
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (onTerminate != null && typeof onTerminateOrMeta !== 'function') {
|
|
69
|
+
throw new Error('onTerminate must be a function or null')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (meta != null && typeof meta !== 'object') {
|
|
73
|
+
throw new Error('meta must be an object or null')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const pkg = meta?.url
|
|
77
|
+
? JSON.parse(readFileSync(new URL('../package.json', meta.url).pathname).toString())
|
|
78
|
+
: null
|
|
79
|
+
|
|
52
80
|
/** @type {Array<rxjs.Subscription|Function|AsyncFunction|Disposable|AsyncDisposable>} */
|
|
53
81
|
const destroyers = []
|
|
54
82
|
|
|
@@ -119,6 +147,9 @@ export function makeApp(appConfig, onTerminate) {
|
|
|
119
147
|
}
|
|
120
148
|
}
|
|
121
149
|
|
|
150
|
+
appConfig.name ||= pkg?.name ?? null
|
|
151
|
+
appConfig.version ||= pkg?.version ?? null
|
|
152
|
+
|
|
122
153
|
assert(appConfig.name, 'name is required')
|
|
123
154
|
|
|
124
155
|
const appDestroyers = []
|
package/couch.d.ts
CHANGED
package/numa.js
CHANGED
|
@@ -3,6 +3,21 @@ import path from 'node:path'
|
|
|
3
3
|
|
|
4
4
|
import { sched_setaffinity } from '@nxtedition/sched'
|
|
5
5
|
|
|
6
|
+
function parseRange(value) {
|
|
7
|
+
const range = []
|
|
8
|
+
for (const part of value.split(',')) {
|
|
9
|
+
if (part.includes('-')) {
|
|
10
|
+
const [start, end] = part.split('-').map(Number)
|
|
11
|
+
for (let i = start; i <= end; i++) {
|
|
12
|
+
range.push(i)
|
|
13
|
+
}
|
|
14
|
+
} else {
|
|
15
|
+
range.push(Number(part))
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return range
|
|
19
|
+
}
|
|
20
|
+
|
|
6
21
|
/**
|
|
7
22
|
*
|
|
8
23
|
* @param {number|number[]} numa
|
|
@@ -14,6 +29,8 @@ export function setAffinity(numa) {
|
|
|
14
29
|
throw new Error('NUMA node must be a non-negative integer')
|
|
15
30
|
}
|
|
16
31
|
|
|
32
|
+
const isolated = parseRange(fs.readFileSync('/sys/devices/system/cpu/isolated', 'utf8').trim())
|
|
33
|
+
|
|
17
34
|
const allNodes = []
|
|
18
35
|
for (const entry of fs.readdirSync('/sys/devices/system/node')) {
|
|
19
36
|
if (!entry.startsWith('node')) {
|
|
@@ -23,25 +40,17 @@ export function setAffinity(numa) {
|
|
|
23
40
|
const cpulist = fs
|
|
24
41
|
.readFileSync(path.join('/sys/devices/system/node', entry, 'cpulist'), 'utf8')
|
|
25
42
|
.trim()
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (part.includes('-')) {
|
|
29
|
-
const [start, end] = part.split('-').map(Number)
|
|
30
|
-
for (let i = start; i <= end; i++) {
|
|
31
|
-
cpus.push(i)
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
cpus.push(Number(part))
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
allNodes.push(cpus)
|
|
43
|
+
|
|
44
|
+
allNodes.push(parseRange(cpulist))
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
if (allNodes.length === 0) {
|
|
41
48
|
throw new Error('No NUMA nodes found')
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
const affinity = indices
|
|
51
|
+
const affinity = indices
|
|
52
|
+
.flatMap((i) => allNodes[i % allNodes.length] ?? [])
|
|
53
|
+
.filter((cpu) => !isolated.includes(cpu))
|
|
45
54
|
sched_setaffinity(0, affinity)
|
|
46
55
|
globalThis.__nxt_sched_affinity = {
|
|
47
56
|
cpulist: affinity,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/lib",
|
|
3
|
-
"version": "27.0.0
|
|
3
|
+
"version": "27.0.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"author": "Robert Nagy <robert.nagy@boffins.se>",
|
|
6
6
|
"type": "module",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"pino": ">=7.0.0",
|
|
88
88
|
"rxjs": "^7.0.0"
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "8c7a9f6b7dbf185d39f5927c779265415fb29bfb"
|
|
91
91
|
}
|