diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index e60ccd18cf9027..54db7ae2fc4aa5 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -3019,6 +3019,21 @@ should have the same effect. The receiving end should also check the [`readable.readableEnded`][] value on [`http.IncomingMessage`][] to get whether it was an aborted or graceful destroy. +### DEP0157: `process._getActiveRequests()`, `process._getActiveHandles()` private APIs + + + +Type: Runtime + +The `process._getActiveRequests()` and `process._getActiveHandles()` functions +are not needed anymore because the `async_hooks` module already provides +functionality that helps us to keep a track of the active resources. + [Legacy URL API]: url.md#legacy-url-api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index ae4eac502803e7..243290eb787638 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -146,9 +146,16 @@ const rawMethods = internalBinding('process_methods'); process.dlopen = rawMethods.dlopen; process.uptime = rawMethods.uptime; - // TODO(joyeecheung): either remove them or make them public - process._getActiveRequests = rawMethods._getActiveRequests; - process._getActiveHandles = rawMethods._getActiveHandles; + process._getActiveRequests = deprecate( + rawMethods._getActiveRequests, + 'process._getActiveRequests() is deprecated. Please use the `async_hooks`' + + ' module instead.', + 'DEP0157'); + process._getActiveHandles = deprecate( + rawMethods._getActiveHandles, + 'process._getActiveHandles() is deprecated. Please use the `async_hooks`' + + ' module instead.', + 'DEP0157'); // TODO(joyeecheung): remove these process.reallyExit = rawMethods.reallyExit; diff --git a/test/parallel/test-async-hooks-track-active-handles.js b/test/parallel/test-async-hooks-track-active-handles.js new file mode 100644 index 00000000000000..b80d4c45aa27cf --- /dev/null +++ b/test/parallel/test-async-hooks-track-active-handles.js @@ -0,0 +1,61 @@ +'use strict'; + +require('../common'); + +const assert = require('assert'); +const async_hooks = require('async_hooks'); +const net = require('net'); + +const activeHandles = new Map(); +async_hooks.createHook({ + init(asyncId, type, triggerAsyncId, resource) { + if (['TCPSERVERWRAP', 'TCPWRAP'].includes(type)) + activeHandles.set(asyncId, resource); + }, + destroy(asyncId) { + activeHandles.delete(asyncId); + } +}).enable(); + +const NUM = 8; +const connections = []; +const clients = []; +let clients_counter = 0; + +const server = net.createServer(function listener(c) { + connections.push(c); +}).listen(0, makeConnection); + + +function makeConnection() { + if (clients_counter >= NUM) return; + net.connect(server.address().port, function connected() { + clientConnected(this); + makeConnection(); + }); +} + + +function clientConnected(client) { + clients.push(client); + if (++clients_counter >= NUM) + checkAll(); +} + + +function checkAll() { + const handles = Array.from(activeHandles.values()); + + clients.forEach(function(item) { + assert.ok(handles.includes(item._handle)); + item.destroy(); + }); + + connections.forEach(function(item) { + assert.ok(handles.includes(item._handle)); + item.end(); + }); + + assert.ok(handles.includes(server._handle)); + server.close(); +} diff --git a/test/parallel/test-async-hooks-track-active-requests.js b/test/parallel/test-async-hooks-track-active-requests.js new file mode 100644 index 00000000000000..201a12b14e5bdc --- /dev/null +++ b/test/parallel/test-async-hooks-track-active-requests.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const async_hooks = require('async_hooks'); +const fs = require('fs'); + +let numFsReqCallbacks = 0; +async_hooks.createHook({ + init(asyncId, type, triggerAsyncId, resource) { + if (type === 'FSREQCALLBACK') + ++numFsReqCallbacks; + }, + destroy(asyncId) { + --numFsReqCallbacks; + } +}).enable(); + +for (let i = 0; i < 12; i++) + fs.open(__filename, 'r', common.mustCall()); + +assert.strictEqual(numFsReqCallbacks, 12); diff --git a/test/parallel/test-process-getactivehandles.js b/test/parallel/test-process-getactivehandles.js index 2db3da3c563e6e..532d6592ca17fb 100644 --- a/test/parallel/test-process-getactivehandles.js +++ b/test/parallel/test-process-getactivehandles.js @@ -1,47 +1,11 @@ 'use strict'; -require('../common'); -const assert = require('assert'); -const net = require('net'); -const NUM = 8; -const connections = []; -const clients = []; -let clients_counter = 0; +const { expectWarning } = require('../common'); -const server = net.createServer(function listener(c) { - connections.push(c); -}).listen(0, makeConnection); +expectWarning( + 'DeprecationWarning', + 'process._getActiveHandles() is deprecated. Please use the `async_hooks` ' + + 'module instead.', + 'DEP0157'); - -function makeConnection() { - if (clients_counter >= NUM) return; - net.connect(server.address().port, function connected() { - clientConnected(this); - makeConnection(); - }); -} - - -function clientConnected(client) { - clients.push(client); - if (++clients_counter >= NUM) - checkAll(); -} - - -function checkAll() { - const handles = process._getActiveHandles(); - - clients.forEach(function(item) { - assert.ok(handles.includes(item)); - item.destroy(); - }); - - connections.forEach(function(item) { - assert.ok(handles.includes(item)); - item.end(); - }); - - assert.ok(handles.includes(server)); - server.close(); -} +process._getActiveHandles(); diff --git a/test/parallel/test-process-getactiverequests.js b/test/parallel/test-process-getactiverequests.js index ed3c0c8fe861ec..b662695e6fbc95 100644 --- a/test/parallel/test-process-getactiverequests.js +++ b/test/parallel/test-process-getactiverequests.js @@ -1,10 +1,11 @@ 'use strict'; -const common = require('../common'); -const assert = require('assert'); -const fs = require('fs'); +const { expectWarning } = require('../common'); -for (let i = 0; i < 12; i++) - fs.open(__filename, 'r', common.mustCall()); +expectWarning( + 'DeprecationWarning', + 'process._getActiveRequests() is deprecated. Please use the `async_hooks` ' + + 'module instead.', + 'DEP0157'); -assert.strictEqual(process._getActiveRequests().length, 12); +process._getActiveRequests(); diff --git a/test/pseudo-tty/ref_keeps_node_running.js b/test/pseudo-tty/ref_keeps_node_running.js index 52761c140eddac..725ac3c32dc8d0 100644 --- a/test/pseudo-tty/ref_keeps_node_running.js +++ b/test/pseudo-tty/ref_keeps_node_running.js @@ -13,18 +13,14 @@ const handle = new TTY(0); handle.readStart(); handle.onread = () => {}; -function isHandleActive(handle) { - return process._getActiveHandles().some((active) => active === handle); -} - -strictEqual(isHandleActive(handle), true, 'TTY handle not initially active'); +strictEqual(handle.hasRef(), true, 'TTY handle not initially active'); handle.unref(); -strictEqual(isHandleActive(handle), false, 'TTY handle active after unref()'); +strictEqual(handle.hasRef(), false, 'TTY handle active after unref()'); handle.ref(); -strictEqual(isHandleActive(handle), true, 'TTY handle inactive after ref()'); +strictEqual(handle.hasRef(), true, 'TTY handle inactive after ref()'); handle.unref(); diff --git a/test/sequential/test-net-connect-econnrefused.js b/test/sequential/test-net-connect-econnrefused.js index 4fd4f8b6943e3c..4e5db3f6948a4d 100644 --- a/test/sequential/test-net-connect-econnrefused.js +++ b/test/sequential/test-net-connect-econnrefused.js @@ -23,9 +23,30 @@ // Verify that connect reqs are properly cleaned up. const common = require('../common'); + const assert = require('assert'); +const async_hooks = require('async_hooks'); const net = require('net'); +const activeRequestsMap = new Map(); +const activeHandlesMap = new Map(); +async_hooks.createHook({ + init(asyncId, type, triggerAsyncId, resource) { + switch (type) { + case 'TCPCONNECTWRAP': + activeRequestsMap.set(asyncId, resource); + break; + case 'TCPWRAP': + activeHandlesMap.set(asyncId, resource); + break; + } + }, + destroy(asyncId) { + activeRequestsMap.delete(asyncId); + activeHandlesMap.delete(asyncId); + } +}).enable(); + const ROUNDS = 5; const ATTEMPTS_PER_ROUND = 50; let rounds = 1; @@ -54,9 +75,10 @@ function pummel() { function check() { setTimeout(common.mustCall(function() { - assert.strictEqual(process._getActiveRequests().length, 0); - const activeHandles = process._getActiveHandles(); - assert.ok(activeHandles.every((val) => val.constructor.name !== 'Socket')); + const activeRequests = Array.from(activeRequestsMap.values()); + assert.strictEqual(activeRequests.length, 0); + const activeHandles = Array.from(activeHandlesMap.values()); + assert.ok(activeHandles.every((val) => val.constructor.name === 'TCP')); }), 0); }