@nxtedition/lib 26.0.37 → 26.1.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.
Files changed (3) hide show
  1. package/app.js +15 -55
  2. package/numa.js +42 -0
  3. package/package.json +2 -1
package/app.js CHANGED
@@ -37,8 +37,8 @@ import { isTimeBetween } from './time.js'
37
37
  import makeUnderPressure from './under-pressure.js'
38
38
  import undici from '@nxtedition/undici'
39
39
  import { isPrimary } from 'node:cluster'
40
- import path from 'node:path'
41
- import { nice, sched_setaffinity } from '@nxtedition/sched'
40
+ import { nice } from '@nxtedition/sched'
41
+ import { setAffinity } from './numa.js'
42
42
 
43
43
  export function makeApp(appConfig, onTerminate) {
44
44
  let ds
@@ -317,61 +317,21 @@ export function makeApp(appConfig, onTerminate) {
317
317
 
318
318
  let affinity = null
319
319
 
320
- const numa = appConfig.numa ?? config.numa
321
- if (process.platform === 'linux' && (isMainThread || numa != null) && numa !== false) {
322
- const allNodes = []
323
- for (const entry of fs.readdirSync('/sys/devices/system/node')) {
324
- if (!entry.startsWith('node')) {
325
- continue
326
- }
327
-
328
- const cpulist = fs
329
- .readFileSync(path.join('/sys/devices/system/node', entry, 'cpulist'), 'utf8')
330
- .trim()
331
- const cpus = []
332
- for (const part of cpulist.split(',')) {
333
- if (part.includes('-')) {
334
- const [start, end] = part.split('-').map(Number)
335
- for (let i = start; i <= end; i++) {
336
- cpus.push(i)
337
- }
338
- } else {
339
- cpus.push(Number(part))
340
- }
341
- }
342
- allNodes.push(cpus)
343
- }
344
-
345
- let indices = []
346
- if (Number.isInteger(numa)) {
347
- indices = [numa % allNodes.length]
348
- } else if (
349
- numa == null ||
350
- numa === true ||
351
- numa === 'auto' ||
352
- numa === 'hash' ||
353
- numa === 'default'
354
- ) {
355
- indices = [hashString(JSON.stringify({ serviceName, serviceModule })) % allNodes.length]
320
+ if (
321
+ process.platform === 'linux' &&
322
+ (isMainThread || appConfig.numa != null) &&
323
+ appConfig.numa !== false
324
+ ) {
325
+ let numa = appConfig.numa
326
+ if (numa == null || numa === true) {
327
+ numa = hashString(JSON.stringify({ serviceName, serviceModule }))
356
328
  }
357
329
 
358
- affinity = indices.flatMap((i) => allNodes[i] ?? [])
359
- if (
360
- Array.isArray(affinity) &&
361
- affinity.length > 0 &&
362
- affinity.every((x) => Number.isInteger(x) && x >= 0)
363
- ) {
364
- try {
365
- sched_setaffinity(0, affinity)
366
- logger.debug({ data: { numa, affinity, indices } }, 'sched_setaffinity succeeded')
367
- } catch (err) {
368
- logger.error(
369
- { err, data: { numa, allNodes, indices, affinity } },
370
- 'sched_setaffinity failed',
371
- )
372
- }
373
- } else {
374
- logger.warn({ data: { numa, allNodes, indices, affinity } }, 'sched_setaffinity failed')
330
+ try {
331
+ affinity = setAffinity(numa)
332
+ logger.debug({ data: { numa: appConfig.numa, affinity } }, 'set numa affinity succeeded')
333
+ } catch (err) {
334
+ logger.error({ err, data: { numa: appConfig.numa } }, 'set numa affinity failed')
375
335
  }
376
336
  }
377
337
 
package/numa.js ADDED
@@ -0,0 +1,42 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+
4
+ import { sched_setaffinity } from '@nxtedition/sched'
5
+
6
+ export function setAffinity(numa) {
7
+ const allNodes = []
8
+ for (const entry of fs.readdirSync('/sys/devices/system/node')) {
9
+ if (!entry.startsWith('node')) {
10
+ continue
11
+ }
12
+
13
+ const cpulist = fs
14
+ .readFileSync(path.join('/sys/devices/system/node', entry, 'cpulist'), 'utf8')
15
+ .trim()
16
+ const cpus = []
17
+ for (const part of cpulist.split(',')) {
18
+ if (part.includes('-')) {
19
+ const [start, end] = part.split('-').map(Number)
20
+ for (let i = start; i <= end; i++) {
21
+ cpus.push(i)
22
+ }
23
+ } else {
24
+ cpus.push(Number(part))
25
+ }
26
+ }
27
+ allNodes.push(cpus)
28
+ }
29
+
30
+ if (allNodes.length === 0) {
31
+ throw new Error('No NUMA nodes found')
32
+ }
33
+
34
+ if (!Number.isInteger(numa) || numa < 0) {
35
+ throw new Error('NUMA node must be a non-negative integer')
36
+ }
37
+
38
+ const indices = [numa % allNodes.length]
39
+ const affinity = indices.flatMap((i) => allNodes[i] ?? [])
40
+ sched_setaffinity(0, affinity)
41
+ return affinity
42
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "26.0.37",
3
+ "version": "26.1.0",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
@@ -27,6 +27,7 @@
27
27
  "logger.js",
28
28
  "logger.d.ts",
29
29
  "mime.js",
30
+ "numa.js",
30
31
  "proxy.js",
31
32
  "timers.js",
32
33
  "trace.js",