@nxtedition/lib 16.0.12 → 17.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 (3) hide show
  1. package/app.js +42 -37
  2. package/logger.js +3 -47
  3. package/package.json +1 -1
package/app.js CHANGED
@@ -3,7 +3,6 @@ import net from 'node:net'
3
3
  import stream from 'node:stream'
4
4
  import { Buffer } from 'node:buffer'
5
5
  import { getDockerSecretsSync } from './docker-secrets.js'
6
- import { getGlobalDispatcher } from 'undici'
7
6
  import fp from 'lodash/fp.js'
8
7
  import { isMainThread, parentPort } from 'node:worker_threads'
9
8
  import toobusy from 'toobusy-js'
@@ -116,57 +115,63 @@ export function makeApp(appConfig, onTerminate) {
116
115
  } (module:${serviceModule}; instance:${serviceInstanceId}) Node/${process.version}`) ??
117
116
  null)
118
117
 
119
- const terminate = async (finalLogger) => {
120
- finalLogger ??= logger
118
+ {
119
+ const loggerConfig = { ...appConfig.logger, ...config.logger }
120
+
121
+ logger = createLogger({
122
+ ...loggerConfig,
123
+ name: serviceName,
124
+ module: serviceModule,
125
+ base: loggerConfig?.base ? { ...loggerConfig.base } : {},
126
+ })
127
+
128
+ destroyers.push(
129
+ () =>
130
+ new Promise((resolve, reject) =>
131
+ logger.flush((err) => (err ? reject(err) : resolve(null))),
132
+ ),
133
+ )
134
+ }
135
+
136
+ let terminated = false
137
+ const terminate = async () => {
138
+ if (terminated) {
139
+ return
140
+ }
141
+
142
+ terminated = true
121
143
 
122
144
  ac.abort()
123
145
 
124
- try {
125
- if (onTerminate) {
126
- try {
127
- await onTerminate(finalLogger)
128
- } catch (err) {
129
- finalLogger.error({ err }, 'terminate error')
130
- }
146
+ if (onTerminate) {
147
+ try {
148
+ await onTerminate(logger)
149
+ } catch (err) {
150
+ logger.error({ err }, 'terminate error')
131
151
  }
152
+ }
132
153
 
133
- const dispatcher = getGlobalDispatcher()
134
- if (dispatcher?.close) {
135
- destroyers.push(async () => {
136
- const timeout = setTimeout(() => {
137
- dispatcher.destroy()
138
- }, 4e3)
139
- await dispatcher.close()
140
- clearTimeout(timeout)
141
- })
154
+ for (const { reason } of await Promise.allSettled(
155
+ destroyers.filter(Boolean).map((fn) => fn(logger)),
156
+ )) {
157
+ if (reason) {
158
+ logger.error({ err: reason }, 'shutdown error')
142
159
  }
143
-
144
- await Promise.all(destroyers.filter(Boolean).map((fn) => fn(finalLogger)))
145
- } catch (err) {
146
- finalLogger.error({ err }, 'shutdown error')
147
160
  }
148
- }
149
161
 
150
- {
151
- const loggerConfig = { ...appConfig.logger, ...config.logger }
152
-
153
- logger = createLogger(
154
- {
155
- ...loggerConfig,
156
- name: serviceName,
157
- module: serviceModule,
158
- base: loggerConfig?.base ? { ...loggerConfig.base } : {},
159
- },
160
- terminate,
161
- )
162
+ setTimeout(() => {
163
+ process.exit(0)
164
+ }, 10e3).unref()
162
165
  }
163
166
 
167
+ process.on('beforeExit', terminate).on('SIGINT', terminate).on('SIGTERM', terminate)
168
+
164
169
  logger.debug({ data: JSON.stringify(config, null, 2) }, 'config')
165
170
 
166
171
  if (!isMainThread && parentPort) {
167
172
  parentPort.on('message', ({ type }) => {
168
173
  if (type === 'nxt:worker:terminate') {
169
- terminate(null)
174
+ terminate()
170
175
  }
171
176
  })
172
177
  }
package/logger.js CHANGED
@@ -1,9 +1,7 @@
1
- import fs from 'node:fs'
2
- import util from 'node:util'
1
+ import assert from 'node:assert'
3
2
  import { isMainThread } from 'node:worker_threads'
4
3
  import serializers from './serializers.js'
5
4
  import pino from 'pino'
6
- import xuid from 'xuid'
7
5
 
8
6
  const isProduction = process.env.NODE_ENV === 'production'
9
7
 
@@ -11,6 +9,8 @@ export function createLogger(
11
9
  { level = isProduction ? 'debug' : 'trace', flushInterval = 1e3, stream = null, ...options } = {},
12
10
  onTerminate,
13
11
  ) {
12
+ assert(!onTerminate)
13
+
14
14
  if (!stream) {
15
15
  if (
16
16
  process.stdout.write !== process.stdout.constructor.prototype.write ||
@@ -55,49 +55,5 @@ export function createLogger(
55
55
  stream,
56
56
  )
57
57
 
58
- let called = false
59
- const finalHandler = async (err, evt) => {
60
- if (called) {
61
- return
62
- }
63
- called = true
64
-
65
- try {
66
- fs.writeFileSync(`/tmp/${new Date()}-${xuid()}`, util.inspect(err), 'utf8')
67
- } catch {
68
- // Do nothing...
69
- }
70
-
71
- if (err) {
72
- if (!(err instanceof Error)) {
73
- err = new Error(err)
74
- }
75
- logger.fatal({ err }, evt || 'error caused exit')
76
-
77
- logger.flush()
78
- } else {
79
- logger.info(`${evt} caught`)
80
-
81
- let exitSignal
82
- try {
83
- exitSignal = onTerminate ? await onTerminate(logger) : null
84
- } catch (err) {
85
- exitSignal = err.exitSignal || 1
86
- logger.warn({ err })
87
- }
88
-
89
- logger.info({ exitSignal }, 'exit')
90
-
91
- logger.flush()
92
- }
93
- }
94
-
95
- process.on('exit', () => finalHandler(null, 'exit'))
96
- process.on('beforeExit', () => finalHandler(null, 'beforeExit'))
97
- process.on('SIGINT', () => finalHandler(null, 'SIGINT'))
98
- process.on('SIGQUIT', () => finalHandler(null, 'SIGQUIT'))
99
- process.on('SIGTERM', () => finalHandler(null, 'SIGTERM'))
100
- process.on('uncaughtException', (err, origin) => finalHandler(err, origin))
101
-
102
58
  return logger
103
59
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "16.0.12",
3
+ "version": "17.0.0",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",