@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.
Files changed (4) hide show
  1. package/app.js +38 -7
  2. package/couch.d.ts +1 -0
  3. package/numa.js +22 -13
  4. 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 { getDockerSecretsSync } from './docker-secrets.js'
11
- import { getUTCRangeForLocalTime } from './time.js'
12
- import fp from 'lodash/fp.js'
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
- export function makeApp(appConfig, onTerminate) {
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
@@ -21,6 +21,7 @@ export interface CouchRequestOptions<Stream extends boolean = false> {
21
21
  bodyTimeout?: number
22
22
  dispatcher?: Dispatcher
23
23
  query?: {
24
+ key?: string
24
25
  startkey?: string
25
26
  endkey?: string
26
27
  update?: boolean
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
- const cpus = []
27
- for (const part of cpulist.split(',')) {
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.flatMap((i) => allNodes[i % allNodes.length] ?? [])
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-alpha.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": "7e4d71a9276d64d7cb8c39eaed681121903e16a4"
90
+ "gitHead": "8c7a9f6b7dbf185d39f5927c779265415fb29bfb"
91
91
  }