1'use strict';
2const common = require('../common');
3
4const { Worker } = require('worker_threads');
5const { createHook } = require('async_hooks');
6const { deepStrictEqual, strictEqual } = require('assert');
7
8const m = new Map();
9createHook({
10  init(asyncId, type, triggerAsyncId, resource) {
11    if (['WORKER', 'MESSAGEPORT'].includes(type)) {
12      m.set(asyncId, { type, resource });
13    }
14  },
15  destroy(asyncId) {
16    m.delete(asyncId);
17  }
18}).enable();
19
20function getActiveWorkerAndMessagePortTypes() {
21  const activeWorkerAndMessagePortTypes = [];
22  for (const asyncId of m.keys()) {
23    const { type, resource } = m.get(asyncId);
24    // Same logic as https://github.com/mafintosh/why-is-node-running/blob/24fb4c878753390a05d00959e6173d0d3c31fddd/index.js#L31-L32.
25    if (typeof resource.hasRef !== 'function' || resource.hasRef() === true) {
26      activeWorkerAndMessagePortTypes.push(type);
27    }
28  }
29  return activeWorkerAndMessagePortTypes;
30}
31
32const w = new Worker('', { eval: true });
33deepStrictEqual(getActiveWorkerAndMessagePortTypes(), ['WORKER']);
34w.unref();
35deepStrictEqual(getActiveWorkerAndMessagePortTypes(), []);
36w.ref();
37deepStrictEqual(getActiveWorkerAndMessagePortTypes(), ['WORKER', 'MESSAGEPORT']);
38
39w.on('exit', common.mustCall((exitCode) => {
40  strictEqual(exitCode, 0);
41  deepStrictEqual(getActiveWorkerAndMessagePortTypes(), ['WORKER']);
42  setTimeout(common.mustCall(() => {
43    deepStrictEqual(getActiveWorkerAndMessagePortTypes(), []);
44  }), 0);
45}));
46