@nxtedition/lib 26.0.25 → 26.0.27

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 (2) hide show
  1. package/app.js +63 -0
  2. package/package.json +3 -1
package/app.js CHANGED
@@ -37,6 +37,10 @@ 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 { nice } from '@napi-rs/nice'
41
+ import path from 'node:path'
42
+
43
+ import { sched_setaffinity, sched_getaffinity } from '@nxtedition/sched'
40
44
 
41
45
  export function makeApp(appConfig, onTerminate) {
42
46
  let ds
@@ -299,6 +303,65 @@ export function makeApp(appConfig, onTerminate) {
299
303
 
300
304
  let toobusy
301
305
 
306
+ if (appConfig.nice && process.platform === 'linux') {
307
+ // Increase priority to reduce latency.
308
+ try {
309
+ nice(appConfig.nice ?? -5)
310
+ logger.debug('nice succeeded')
311
+ } catch (err) {
312
+ logger.error({ err }, 'nice failed')
313
+ }
314
+ }
315
+
316
+ if (appConfig.affinity != null && process.platform === 'linux') {
317
+ try {
318
+ const nodes = []
319
+ for (const entry of fs.readdirSync('/sys/devices/system/node')) {
320
+ if (!entry.startsWith('node')) {
321
+ continue
322
+ }
323
+
324
+ const cpulist = fs
325
+ .readFileSync(path.join('/sys/devices/system/node', entry, 'cpulist'), 'utf8')
326
+ .trim()
327
+ const cpus = []
328
+ for (const part of cpulist.split(',')) {
329
+ if (part.includes('-')) {
330
+ const [start, end] = part.split('-').map(Number)
331
+ for (let i = start; i <= end; i++) cpus.push(i)
332
+ } else {
333
+ cpus.push(Number(part))
334
+ }
335
+ }
336
+ nodes.push(cpus)
337
+ }
338
+
339
+ let indices
340
+ if (typeof appConfig.affinity === 'number') {
341
+ indices = [appConfig.affinity]
342
+ } else if (Array.isArray(appConfig.affinity)) {
343
+ indices = appConfig.affinity
344
+ } else {
345
+ indices = [Math.floor(Math.random() * nodes.length)]
346
+ }
347
+
348
+ if (indices?.length > 0) {
349
+ let affinity = []
350
+ for (const index of indices) {
351
+ affinity = fp.union(affinity, nodes[index % nodes.length])
352
+ }
353
+
354
+ const next = affinity
355
+ const prev = sched_getaffinity(0)
356
+
357
+ sched_setaffinity(0, fp.intersection(prev, next))
358
+ logger.debug({ data: { prev, next, nodes, affinity } }, 'sched_setaffinity succeeded')
359
+ }
360
+ } catch (err) {
361
+ logger.error({ err }, 'sched_setaffinity failed')
362
+ }
363
+ }
364
+
302
365
  if (appConfig.toobusy) {
303
366
  const resolution = appConfig.toobusy.resolution ?? 10
304
367
  const interval = appConfig.toobusy.interval ?? 500
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "26.0.25",
3
+ "version": "26.0.27",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
@@ -66,7 +66,9 @@
66
66
  "@aws-sdk/client-s3": "3.873.0",
67
67
  "@elastic/elasticsearch": "^8.17.1",
68
68
  "@elastic/transport": "^8.9.3",
69
+ "@napi-rs/nice": "^1.1.1",
69
70
  "@nxtedition/nxt-undici": "^6.4.0",
71
+ "@nxtedition/sched": "^1.0.1",
70
72
  "@smithy/node-http-handler": "^4.1.1",
71
73
  "acorn": "^8.15.0",
72
74
  "astring": "^1.9.0",