Skip to content

Instantly share code, notes, and snippets.

@krisselden
Last active April 22, 2020 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krisselden/6db95b4e324be489265f57f7ff7ce396 to your computer and use it in GitHub Desktop.
Save krisselden/6db95b4e324be489265f57f7ff7ce396 to your computer and use it in GitHub Desktop.
import async_hooks from 'async_hooks';
import fs from 'fs';
function createSyncOut() {
let indent = 2;
return [
function putln(msg) {
const indentStr = ' '.repeat(Math.max(0, indent));
fs.writeSync(1, `${indentStr}${msg}\n`);
},
function increment() {
indent += 2;
},
function decrement() {
indent -= 2;
},
];
}
const [putln, indent, outdent] = createSyncOut();
async_hooks
.createHook({
init(asyncId, type, triggerAsyncId) {
const eid = async_hooks.executionAsyncId();
putln(`init ${type}(${asyncId}): tid=${triggerAsyncId} eid=${eid}`);
},
before(asyncId) {
putln(`before: ${asyncId}`);
indent();
},
after(asyncId) {
outdent();
putln(`after: ${asyncId}`);
},
destroy(asyncId) {
putln(`destroy: ${asyncId}`);
},
})
.enable();
const asyncLocalStorage = new async_hooks.AsyncLocalStorage();
function startAsync(label, callback) {
putln(`startAsync "${label}"`);
asyncLocalStorage.run(label, callback);
}
function logWithId(msg) {
const label = asyncLocalStorage.getStore();
const eid = async_hooks.executionAsyncId();
const tid = async_hooks.triggerAsyncId();
putln(
`"${label !== undefined ? label : '-'}" <tid=${tid} eid=${eid}>: ${msg}`
);
}
process.on('uncaughtException', (err, origin) => {
logWithId(`EVENT uncaughtException: ${err} ${origin}`);
});
process.on('unhandledRejection', (reason, promise) => {
logWithId(`EVENT unhandledRejection: ${reason} ${promise}`);
});
process.on('rejectionHandled', (promise) => {
logWithId(`EVENT rejectionHandled: ${promise}`);
});
startAsync('unhandled_error', () => {
setTimeout(() => {
setTimeout(() => {
throw new Error('unhandled timeout error');
});
}, 400);
setImmediate(() => {
throw new Error('unhandled immediate error');
});
});
let cached;
let cachedRejected;
startAsync('produce_cached', () => {
cached = Promise.resolve().then(() => {
logWithId('produce cached value');
});
});
startAsync('float_rejected', () => {
cachedRejected = Promise.resolve().then(() => {
throw new Error('produce cached error');
});
});
startAsync('chain_cached_rejected', () => {
setTimeout(() => {
cachedRejected.catch((err) => logWithId(`handle chached reject: ${err}`));
}, 1000);
});
startAsync('chain_cached', () => {
setTimeout(() => {
cached.then(() => logWithId('after chached'));
}, 1000);
});
function doAsyncWithCallback(callback) {
startAsync('async_with_callback', () => {
setTimeout(() => {
logWithId('invoke outside callback');
callback();
}, 1000);
});
}
doAsyncWithCallback(() => {
logWithId('throw from outside callback');
throw new Error('error from callback');
});
function readFile(shouldThrow = false) {
const stream = fs.createReadStream('package.json', { encoding: 'utf8' });
stream.on('data', () => {
if (shouldThrow) {
throw Error('read handler error');
}
logWithId('file data');
});
stream.on('end', () => {
logWithId('file end');
});
stream.on('close', () => {
logWithId('file close');
});
}
startAsync('read_file', () => {
readFile();
});
startAsync('read_error', () => {
readFile(true);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment