why-is-node-still-running
Version:
Find out exactly why Node is still running.
209 lines (207 loc) • 9.2 kB
JavaScript
module.exports = (() => {
const defines = {};
const entry = [null];
function define(name, dependencies, factory) {
defines[name] = { dependencies, factory };
entry[0] = name;
}
define("require", ["exports"], (exports) => {
Object.defineProperty(exports, "__cjsModule", { value: true });
Object.defineProperty(exports, "default", { value: (name) => resolve(name) });
});
/*!
* Copyright 2012 the V8 project authors. All rights reserved. Redistribution
* and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Google Inc. nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
define("lib/format", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatStackTrace = void 0;
function formatStackTrace(error, frames) {
const lines = [];
try {
lines.push(error.toString());
}
catch (e) {
try {
lines.push('<error: ' + e + ">");
}
catch (ee) {
lines.push('<error>');
}
}
for (const frame of frames) {
let line;
try {
line = frame.toString();
}
catch (e) {
try {
line = '<error: ' + e + '>';
}
catch (ee) {
line = '<error>';
}
}
lines.push(' at ' + line);
}
return lines.join('\n');
}
exports.formatStackTrace = formatStackTrace;
});
/*! https://github.com/defunctzombie/node-stackback/blob/master/index.js */
define("lib/stackback", ["require", "exports", "lib/format"], function (require, exports, format_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.stackback = void 0;
function stackback(error) {
const save = Error.prepareStackTrace;
Error.prepareStackTrace = function (err, trace) {
Object.defineProperty(err, '_sb_callsites', { value: trace });
return (save || format_1.formatStackTrace)(err, trace);
};
error.stack;
if (!error._sb_callsites) {
return [];
}
Error.prepareStackTrace = save;
return error._sb_callsites;
}
exports.stackback = stackback;
});
/*!
* why-is-node-still-running
*
* Find out exactly why Node is still running.
*
* Copyright (c) 2020-present, cheap glitch
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
define("index", ["require", "exports", "path", "fs", "async_hooks", "lib/stackback"], function (require, exports, path_1, fs_1, async_hooks_1, stackback_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.whyIsNodeStillRunning = void 0;
const active = new Map();
const hook = async_hooks_1.createHook({
init(id, type, _, resource) {
if (type == 'TIMERWRAP' || type == 'PROMISE') {
return;
}
const error = new Error();
const stacks = stackback_1.stackback(error);
active.set(id, { type, stacks, resource });
},
destroy(id) {
active.delete(id);
},
});
hook.enable();
function whyIsNodeStillRunning(logger = console) {
hook.disable();
const activeResources = [...active.values()].filter(resource => resource.type != 'Timeout'
|| typeof resource.resource.hasRef != 'function'
|| resource.resource.hasRef());
logger.error(`There are ${activeResources.length} handle(s) keeping the process running:`);
activeResources.forEach(resource => printStacks(logger, resource));
}
exports.whyIsNodeStillRunning = whyIsNodeStillRunning;
function printStacks(logger, resource) {
const stacks = resource.stacks.slice(1).filter((stack) => {
const filename = stack.getFileName();
return (filename && filename.includes(path_1.sep) && filename.indexOf('internal' + path_1.sep) != 0);
});
logger.error('\n' + resource.type);
if (!stacks[0]) {
logger.error('(unknown stack trace)');
return;
}
const padding = ' '.repeat(Math.max(...stacks.map((stack) => (stack.getFileName() + ':' + stack.getLineNumber()).length)));
for (const stack of stacks) {
const prefix = stack.getFileName() + ':' + stack.getLineNumber();
if (fs_1.existsSync(stack.getFileName())) {
const src = fs_1.readFileSync(stack.getFileName(), 'utf8').split(/\n|\r\n/);
logger.error(prefix + padding.slice(prefix.length) + ' - ' + src[stack.getLineNumber() - 1].trim());
}
else {
logger.error(prefix + padding.slice(prefix.length));
}
}
}
});
'marker:resolver';
function get_define(name) {
if (defines[name]) {
return defines[name];
}
else if (defines[name + '/index']) {
return defines[name + '/index'];
}
else {
const dependencies = ['exports'];
const factory = (exports) => {
try {
Object.defineProperty(exports, "__cjsModule", { value: true });
Object.defineProperty(exports, "default", { value: require(name) });
}
catch (_a) {
throw Error(['module "', name, '" not found.'].join(''));
}
};
return { dependencies, factory };
}
}
const instances = {};
function resolve(name) {
if (instances[name]) {
return instances[name];
}
if (name === 'exports') {
return {};
}
const define = get_define(name);
instances[name] = {};
const dependencies = define.dependencies.map(name => resolve(name));
define.factory(...dependencies);
const exports = dependencies[define.dependencies.indexOf('exports')];
instances[name] = (exports['__cjsModule']) ? exports.default : exports;
return instances[name];
}
if (entry[0] !== null) {
return resolve(entry[0]);
}
})();