@remit/logger-lambda 0.0.13 → 0.0.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/logger-lambda",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -67,6 +67,23 @@ const one = (emit: () => void): Line => {
67
67
  return lines[0];
68
68
  };
69
69
 
70
+ // Both scopes have to be open at the same moment for a leak to be observable;
71
+ // a gate each side waits on pins that interleaving.
72
+ const gate = (): { reached: Promise<void>; pass: () => void } => {
73
+ let pass!: () => void;
74
+ const reached = new Promise<void>((resolve) => {
75
+ pass = () => resolve();
76
+ });
77
+ return { reached, pass };
78
+ };
79
+
80
+ // Sorted by message, so the comparison covers every line exactly once without
81
+ // naming the order the scheduler happened to finish them in.
82
+ const requestIdPerMessage = (lines: Line[]): [string, unknown][] =>
83
+ lines
84
+ .map((line): [string, unknown] => [String(line.msg), line.requestId])
85
+ .sort(([left], [right]) => left.localeCompare(right));
86
+
70
87
  describe("log output", () => {
71
88
  it("writes one JSON object per line on stdout", () => {
72
89
  const log = createLogger();
@@ -311,25 +328,30 @@ describe("withLogContext", () => {
311
328
  });
312
329
 
313
330
  it("keeps overlapping scopes apart across awaits", async () => {
314
- const request = (id: string, delayMs: number) =>
315
- withLogContext({ requestId: id }, async () => {
316
- await new Promise((resolve) => setTimeout(resolve, delayMs));
317
- logger.warn(`handled ${id}`);
318
- });
331
+ const slowStarted = gate();
332
+ const fastLogged = gate();
319
333
 
320
334
  // The slow request opens its scope first and logs last, which is exactly
321
335
  // the interleaving a shared mutable binding gets wrong.
322
336
  const lines = await captureAsync(async () => {
323
- await Promise.all([request("slow", 10), request("fast", 1)]);
337
+ await Promise.all([
338
+ withLogContext({ requestId: "slow" }, async () => {
339
+ slowStarted.pass();
340
+ await fastLogged.reached;
341
+ logger.warn("handled slow");
342
+ }),
343
+ withLogContext({ requestId: "fast" }, async () => {
344
+ await slowStarted.reached;
345
+ logger.warn("handled fast");
346
+ fastLogged.pass();
347
+ }),
348
+ ]);
324
349
  });
325
350
 
326
- assert.deepEqual(
327
- lines.map((line) => [line.msg, line.requestId]),
328
- [
329
- ["handled fast", "fast"],
330
- ["handled slow", "slow"],
331
- ],
332
- );
351
+ assert.deepEqual(requestIdPerMessage(lines), [
352
+ ["handled fast", "fast"],
353
+ ["handled slow", "slow"],
354
+ ]);
333
355
  });
334
356
 
335
357
  it("nests, adding to the scope it runs inside", () => {
@@ -404,23 +426,34 @@ describe("withTelemetry", () => {
404
426
  });
405
427
 
406
428
  it("keeps concurrent invocations apart", async () => {
407
- const invoke = (id: string, delayMs: number) =>
408
- withTelemetry(async () => {
409
- await new Promise((resolve) => setTimeout(resolve, delayMs));
410
- logger.warn(`handled ${id}`);
411
- })({}, {
429
+ const slowStarted = gate();
430
+ const fastLogged = gate();
431
+
432
+ const invoke = (id: string, handler: () => Promise<void>) =>
433
+ withTelemetry(handler)({}, {
412
434
  awsRequestId: id,
413
435
  functionName: "test-function",
414
436
  } as unknown as typeof context);
415
437
 
416
438
  const lines = await captureAsync(async () => {
417
- await Promise.all([invoke("slow", 10), invoke("fast", 1)]);
439
+ await Promise.all([
440
+ invoke("slow", async () => {
441
+ slowStarted.pass();
442
+ await fastLogged.reached;
443
+ logger.warn("handled slow");
444
+ }),
445
+ invoke("fast", async () => {
446
+ await slowStarted.reached;
447
+ logger.warn("handled fast");
448
+ fastLogged.pass();
449
+ }),
450
+ ]);
418
451
  });
419
452
 
420
453
  assert.deepEqual(
421
- lines
422
- .filter((line) => String(line.msg).startsWith("handled "))
423
- .map((line) => [line.msg, line.requestId]),
454
+ requestIdPerMessage(
455
+ lines.filter((line) => String(line.msg).startsWith("handled ")),
456
+ ),
424
457
  [
425
458
  ["handled fast", "fast"],
426
459
  ["handled slow", "slow"],
@@ -12,7 +12,6 @@ import {
12
12
  recordImapFailure,
13
13
  recordQueueEvent,
14
14
  recordSmtpFailure,
15
- registry,
16
15
  renderMetrics,
17
16
  resetMetrics,
18
17
  setAccountSyncAges,
@@ -353,7 +352,7 @@ describe("the /metrics endpoint", () => {
353
352
  onError: (error) => reported.push(error),
354
353
  });
355
354
  servers.push(server);
356
- await new Promise((resolve) => setTimeout(resolve, 50));
355
+ await new Promise<void>((resolve) => server.once("error", () => resolve()));
357
356
  assert.equal(reported.length, 1);
358
357
  assert.match(String(reported[0]), /EADDRINUSE/);
359
358
  // The port that was already bound still answers: nothing died.
@@ -370,7 +369,7 @@ describe("the /metrics endpoint", () => {
370
369
  }) as typeof process.stderr.write;
371
370
  const server = startMetricsServer({ port: held, host: "127.0.0.1" });
372
371
  servers.push(server);
373
- await new Promise((resolve) => setTimeout(resolve, 50));
372
+ await new Promise<void>((resolve) => server.once("error", () => resolve()));
374
373
  process.stderr.write = restore;
375
374
 
376
375
  assert.equal(written.length, 1);