@nxtedition/lib 26.0.20 → 26.0.22

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/http.js CHANGED
@@ -13,6 +13,8 @@ export const kAbortController = Symbol('abortController')
13
13
  const ERR_HEADER_EXPR =
14
14
  /^(content-length|content-type|te|host|upgrade|trailers|connection|keep-alive|http2-settings|transfer-encoding|proxy-connection|proxy-authenticate|proxy-authorization)$/i
15
15
 
16
+ const pending = (globalThis._nxt_lib_http_pending = new Set())
17
+
16
18
  // https://github.com/fastify/fastify/blob/main/lib/reqIdGenFactory.js
17
19
  // 2,147,483,647 (2^31 − 1) stands for max SMI value (an internal optimization of V8).
18
20
  // With this upper bound, if you'll be generating 1k ids/sec, you're going to hit it in ~25 days.
@@ -144,10 +146,12 @@ export async function upgradeMiddleware(ctx, next) {
144
146
  }
145
147
  })
146
148
 
149
+ const reqLogger = ctx.logger?.child({ req })
150
+ pending.add(ctx)
147
151
  try {
148
152
  const isHealthcheck = req.url === '/healthcheck' || req.url === '/_up'
149
153
  if (!isHealthcheck) {
150
- ctx.logger?.debug({ req }, 'request started')
154
+ reqLogger?.debug({ req }, 'request started')
151
155
  }
152
156
 
153
157
  const thenable = next()
@@ -165,15 +169,15 @@ export async function upgradeMiddleware(ctx, next) {
165
169
  if (isHealthcheck) {
166
170
  // Do nothing...
167
171
  } else if (socket.errored) {
168
- ctx.logger?.error({ err: socket.errored, req, socket, elapsedTime }, 'stream error')
172
+ reqLogger?.error({ err: socket.errored, req, socket, elapsedTime }, 'stream error')
169
173
  } else if (!socket.writableEnded) {
170
- ctx.logger?.debug({ socket, elapsedTime }, 'stream aborted')
174
+ reqLogger?.debug({ socket, elapsedTime }, 'stream aborted')
171
175
  } else if (socket.statusCode >= 500) {
172
- ctx.logger?.error({ socket, elapsedTime }, 'stream error')
176
+ reqLogger?.error({ socket, elapsedTime }, 'stream error')
173
177
  } else if (socket.statusCode >= 400) {
174
- ctx.logger?.warn({ socket, elapsedTime }, 'stream failed')
178
+ reqLogger?.warn({ socket, elapsedTime }, 'stream failed')
175
179
  } else {
176
- ctx.logger?.debug({ socket, elapsedTime }, 'stream completed')
180
+ reqLogger?.debug({ socket, elapsedTime }, 'stream completed')
177
181
  }
178
182
  } catch (err) {
179
183
  ctx[kAbortController]?.abort(err)
@@ -182,17 +186,18 @@ export async function upgradeMiddleware(ctx, next) {
182
186
  const elapsedTime = performance.now() - startTime
183
187
 
184
188
  if (req.aborted || aborted || (!socket.errored && socket.closed) || err.name === 'AbortError') {
185
- ctx.logger?.debug({ err, req, socket, elapsedTime }, 'stream aborted')
189
+ reqLogger?.debug({ err, req, socket, elapsedTime }, 'stream aborted')
186
190
  } else if (statusCode < 500) {
187
- ctx.logger?.warn({ err, req, socket, elapsedTime }, 'stream failed')
191
+ reqLogger?.warn({ err, req, socket, elapsedTime }, 'stream failed')
188
192
  } else {
189
- ctx.logger?.error({ err, req, socket, elapsedTime }, 'stream error')
193
+ reqLogger?.error({ err, req, socket, elapsedTime }, 'stream error')
190
194
  }
191
195
  socket.destroy(err)
192
196
  } finally {
197
+ pending.delete(ctx)
193
198
  if (!socket.writableEnded && !socket.destroyed) {
194
199
  socket.destroy()
195
- ctx.logger?.warn('socket destroyed')
200
+ reqLogger?.warn('socket destroyed')
196
201
  }
197
202
  }
198
203
  }
@@ -201,10 +206,12 @@ export async function requestMiddleware(ctx, next) {
201
206
  const { req, res, target } = ctx
202
207
  const startTime = performance.now()
203
208
 
209
+ const reqLogger = ctx.logger?.child({ req })
210
+ pending.add(ctx)
204
211
  try {
205
212
  const isHealthcheck = req.url === '/healthcheck' || req.url === '/_up'
206
213
  if (!isHealthcheck) {
207
- ctx.logger?.debug({ req }, 'request started')
214
+ reqLogger?.debug({ req }, 'request started')
208
215
  }
209
216
 
210
217
  if (!target) {
@@ -254,15 +261,15 @@ export async function requestMiddleware(ctx, next) {
254
261
  if (isHealthcheck) {
255
262
  // Do nothing...
256
263
  } else if (res.errored) {
257
- ctx.logger?.error({ err: res.errored, res, elapsedTime }, 'request error')
264
+ reqLogger?.error({ err: res.errored, res, elapsedTime }, 'request error')
258
265
  } else if (!res.writableEnded) {
259
- ctx.logger?.debug({ res, elapsedTime }, 'request aborted')
266
+ reqLogger?.debug({ res, elapsedTime }, 'request aborted')
260
267
  } else if (res.statusCode >= 500) {
261
- ctx.logger?.error({ res, elapsedTime }, 'request error')
268
+ reqLogger?.error({ res, elapsedTime }, 'request error')
262
269
  } else if (res.statusCode >= 400) {
263
- ctx.logger?.warn({ res, elapsedTime }, 'request failed')
270
+ reqLogger?.warn({ res, elapsedTime }, 'request failed')
264
271
  } else {
265
- ctx.logger?.debug({ res, elapsedTime }, 'request completed')
272
+ reqLogger?.debug({ res, elapsedTime }, 'request completed')
266
273
  }
267
274
  } catch (err) {
268
275
  ctx[kAbortController]?.abort(err)
@@ -302,7 +309,7 @@ export async function requestMiddleware(ctx, next) {
302
309
  }
303
310
  }
304
311
  } else if (err.headers != null) {
305
- ctx.logger?.warn({ req, err }, 'invalid headers')
312
+ reqLogger?.warn({ req, err }, 'invalid headers')
306
313
  }
307
314
 
308
315
  if (fp.isPlainObject(err.body)) {
@@ -317,21 +324,22 @@ export async function requestMiddleware(ctx, next) {
317
324
  }
318
325
 
319
326
  if (statusCode < 500) {
320
- ctx.logger?.warn({ req, res, err, elapsedTime }, 'request failed')
327
+ reqLogger?.warn({ req, res, err, elapsedTime }, 'request failed')
321
328
  } else {
322
- ctx.logger?.error({ req, res, err, elapsedTime }, 'request error')
329
+ reqLogger?.error({ req, res, err, elapsedTime }, 'request error')
323
330
  }
324
331
  } else {
325
332
  if (req.aborted || (!res.errored && res.closed) || err.name === 'AbortError') {
326
- ctx.logger?.debug({ req, res, err, elapsedTime }, 'request aborted')
333
+ reqLogger?.debug({ req, res, err, elapsedTime }, 'request aborted')
327
334
  } else if (statusCode < 500) {
328
- ctx.logger?.warn({ req, res, err, elapsedTime }, 'request failed')
335
+ reqLogger?.warn({ req, res, err, elapsedTime }, 'request failed')
329
336
  } else {
330
- ctx.logger?.error({ req, res, err, elapsedTime }, 'request error')
337
+ reqLogger?.error({ req, res, err, elapsedTime }, 'request error')
331
338
  }
332
339
  res.destroy(err)
333
340
  }
334
341
  } finally {
342
+ pending.delete(ctx)
335
343
  if (res.writableEnded || res.destroyed || res.stream?.destroyed) {
336
344
  // Do nothing..
337
345
  } else {
@@ -726,6 +734,7 @@ export async function request(ctx, next) {
726
734
 
727
735
  let reqLogger = logger
728
736
 
737
+ pending.add(ctx)
729
738
  try {
730
739
  ctx.url = requestTarget(req)
731
740
  if (!ctx.url) {
@@ -835,6 +844,7 @@ export async function request(ctx, next) {
835
844
  }
836
845
  }
837
846
  } finally {
847
+ pending.delete(ctx)
838
848
  if (!res.writableEnded) {
839
849
  res.destroy()
840
850
  logger.debug('request destroyed')
@@ -912,6 +922,7 @@ export async function upgrade(ctx, next) {
912
922
 
913
923
  let aborted = false
914
924
  let reqLogger = logger
925
+ pending.add(ctx)
915
926
  try {
916
927
  ctx.url = requestTarget(req)
917
928
  if (!ctx.url) {
@@ -976,6 +987,7 @@ export async function upgrade(ctx, next) {
976
987
 
977
988
  socket.destroy(err)
978
989
  } finally {
990
+ pending.delete(ctx)
979
991
  queueMicrotask(() => ac.abort())
980
992
  }
981
993
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "26.0.20",
3
+ "version": "26.0.22",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
@@ -209,7 +209,7 @@ export function makeTemplateCompiler({ ds, proxify, logger, platform }) {
209
209
  return resolver ? (args$) => resolver(template, args$) : null
210
210
  }
211
211
 
212
- function resolveTemplate(template, args$, options) {
212
+ async function resolveTemplate(template, args$, options) {
213
213
  const expr = _compileTemplate(template)
214
214
  return expr ? firstValueFrom(expr(template, args$), options) : template
215
215
  }