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