• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const tick = require('../common/tick');
6const async_hooks = require('async_hooks');
7const { AsyncResource } = async_hooks;
8
9const initHooks = require('./init-hooks');
10const { checkInvocations } = require('./hook-checks');
11
12const hooks = initHooks();
13hooks.enable();
14
15assert.throws(
16  () => new AsyncResource(), {
17    code: 'ERR_INVALID_ARG_TYPE',
18    name: 'TypeError',
19  });
20assert.throws(() => {
21  new AsyncResource('invalid_trigger_id', { triggerAsyncId: null });
22}, {
23  code: 'ERR_INVALID_ASYNC_ID',
24  name: 'RangeError',
25});
26
27assert.strictEqual(
28  new AsyncResource('default_trigger_id').triggerAsyncId(),
29  async_hooks.executionAsyncId()
30);
31
32// Create first custom event 'alcazares' with triggerAsyncId derived
33// from async_hooks executionAsyncId
34const alcaTriggerId = async_hooks.executionAsyncId();
35const alcaEvent = new AsyncResource('alcazares', alcaTriggerId);
36const alcazaresActivities = hooks.activitiesOfTypes([ 'alcazares' ]);
37
38// Alcazares event was constructed and thus only has an `init` call
39assert.strictEqual(alcazaresActivities.length, 1);
40const alcazares = alcazaresActivities[0];
41assert.strictEqual(alcazares.type, 'alcazares');
42assert.strictEqual(typeof alcazares.uid, 'number');
43assert.strictEqual(alcazares.triggerAsyncId, alcaTriggerId);
44checkInvocations(alcazares, { init: 1 }, 'alcazares constructed');
45
46assert.strictEqual(typeof alcaEvent.asyncId(), 'number');
47assert.notStrictEqual(alcaEvent.asyncId(), alcaTriggerId);
48assert.strictEqual(alcaEvent.triggerAsyncId(), alcaTriggerId);
49
50alcaEvent.runInAsyncScope(() => {
51  checkInvocations(alcazares, { init: 1, before: 1 },
52                   'alcazares emitted before');
53});
54checkInvocations(alcazares, { init: 1, before: 1, after: 1 },
55                 'alcazares emitted after');
56alcaEvent.runInAsyncScope(() => {
57  checkInvocations(alcazares, { init: 1, before: 2, after: 1 },
58                   'alcazares emitted before again');
59});
60checkInvocations(alcazares, { init: 1, before: 2, after: 2 },
61                 'alcazares emitted after again');
62alcaEvent.emitDestroy();
63tick(1, common.mustCall(tick1));
64
65function tick1() {
66  checkInvocations(alcazares, { init: 1, before: 2, after: 2, destroy: 1 },
67                   'alcazares emitted destroy');
68
69  // The below shows that we can pass any number as a trigger id
70  const pobTriggerId = 111;
71  const pobEvent = new AsyncResource('poblado', pobTriggerId);
72  const pobladoActivities = hooks.activitiesOfTypes([ 'poblado' ]);
73  const poblado = pobladoActivities[0];
74  assert.strictEqual(poblado.type, 'poblado');
75  assert.strictEqual(typeof poblado.uid, 'number');
76  assert.strictEqual(poblado.triggerAsyncId, pobTriggerId);
77  checkInvocations(poblado, { init: 1 }, 'poblado constructed');
78  pobEvent.runInAsyncScope(() => {
79    checkInvocations(poblado, { init: 1, before: 1 },
80                     'poblado emitted before');
81  });
82
83  checkInvocations(poblado, { init: 1, before: 1, after: 1 },
84                   'poblado emitted after');
85
86  // After we disable the hooks we shouldn't receive any events anymore
87  hooks.disable();
88  alcaEvent.emitDestroy();
89  tick(1, common.mustCall(tick2));
90
91  function tick2() {
92    checkInvocations(
93      alcazares, { init: 1, before: 2, after: 2, destroy: 1 },
94      'alcazares emitted destroy a second time after hooks disabled');
95    pobEvent.emitDestroy();
96    tick(1, common.mustCall(tick3));
97  }
98
99  function tick3() {
100    checkInvocations(poblado, { init: 1, before: 1, after: 1 },
101                     'poblado emitted destroy after hooks disabled');
102  }
103}
104