• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2// Flags: --expose_gc
3
4const common = require('../common');
5const assert = require('assert');
6const tick = require('../common/tick');
7
8const { createHook, AsyncResource } = require('async_hooks');
9
10// Test priority of destroy hook relative to nextTick,... and
11// verify a microtask is scheduled in case a lot items are queued
12
13const resType = 'MyResource';
14let activeId = -1;
15createHook({
16  init(id, type) {
17    if (type === resType) {
18      assert.strictEqual(activeId, -1);
19      activeId = id;
20    }
21  },
22  destroy(id) {
23    if (activeId === id) {
24      activeId = -1;
25    }
26  }
27}).enable();
28
29function testNextTick() {
30  assert.strictEqual(activeId, -1);
31  const res = new AsyncResource(resType);
32  assert.strictEqual(activeId, res.asyncId());
33  res.emitDestroy();
34  // nextTick has higher prio than emit destroy
35  process.nextTick(common.mustCall(() =>
36    assert.strictEqual(activeId, res.asyncId()))
37  );
38}
39
40function testQueueMicrotask() {
41  assert.strictEqual(activeId, -1);
42  const res = new AsyncResource(resType);
43  assert.strictEqual(activeId, res.asyncId());
44  res.emitDestroy();
45  // queueMicrotask has higher prio than emit destroy
46  queueMicrotask(common.mustCall(() =>
47    assert.strictEqual(activeId, res.asyncId()))
48  );
49}
50
51function testImmediate() {
52  assert.strictEqual(activeId, -1);
53  const res = new AsyncResource(resType);
54  assert.strictEqual(activeId, res.asyncId());
55  res.emitDestroy();
56  setImmediate(common.mustCall(() =>
57    assert.strictEqual(activeId, -1))
58  );
59}
60
61function testPromise() {
62  assert.strictEqual(activeId, -1);
63  const res = new AsyncResource(resType);
64  assert.strictEqual(activeId, res.asyncId());
65  res.emitDestroy();
66  // Promise has higher prio than emit destroy
67  Promise.resolve().then(common.mustCall(() =>
68    assert.strictEqual(activeId, res.asyncId()))
69  );
70}
71
72async function testAwait() {
73  assert.strictEqual(activeId, -1);
74  const res = new AsyncResource(resType);
75  assert.strictEqual(activeId, res.asyncId());
76  res.emitDestroy();
77
78  for (let i = 0; i < 5000; i++) {
79    await Promise.resolve();
80  }
81  global.gc();
82  await Promise.resolve();
83  // Limit to trigger a microtask not yet reached
84  assert.strictEqual(activeId, res.asyncId());
85  for (let i = 0; i < 5000; i++) {
86    await Promise.resolve();
87  }
88  global.gc();
89  await Promise.resolve();
90  assert.strictEqual(activeId, -1);
91}
92
93testNextTick();
94tick(2, testQueueMicrotask);
95tick(4, testImmediate);
96tick(6, testPromise);
97tick(8, () => testAwait().then(common.mustCall()));
98