Skip to content

Instantly share code, notes, and snippets.

@gabrielschulhof
Last active September 12, 2024 21:45
Show Gist options
  • Save gabrielschulhof/e182c6103c500d84c0238623ce3a4292 to your computer and use it in GitHub Desktop.
Save gabrielschulhof/e182c6103c500d84c0238623ce3a4292 to your computer and use it in GitHub Desktop.
import fs from 'node:fs'
import async_hooks from 'node:async_hooks'
import process from 'node:process'
declare global {
var promises: Record<string, number>
var enableHook: () => {}
var disableHook: () => {}
var dumpPromises: () => void
}
global.promises = {}
const sourceMatchRegex = /auction-graph-api[/](src|dist)/
const hook = async_hooks
.createHook({
init: (_, type, __) => {
if (type !== 'PROMISE') return
const stack = String(new Error().stack)
// We don't want stack frames that are exclusively in node_modules or in
// internal node code.
stack
.split('\n')
// At least one stack frame should be in our own source code.
.filter(item => item.search(sourceMatchRegex) >= 0)
// ... but not this very stack frame we're currently in.
.filter(item => !item.trim().startsWith('at AsyncHook.init'))
// If any frames are left, upsert the promises array.
.every(_ => {
global.promises[stack] = (global.promises[stack] || 0) + 1
global.promises.total = (global.promises.total || 0) + 1
// If multiple frames are in our source code, only upsert once.
return false
})
},
})
global.enableHook = () => hook.enable()
global.disableHook = () => hook.disable()
global.dumpPromises = () => {
Object.entries(global.promises)
// Show the total at the end.
.filter(([key, _]) => key !== 'total')
// Print most frequently hit stacks last.
.sort(([_, lValue], [__, rValue]) => lValue - rValue)
// Avoid console.log because it is async.
.forEach(([key, value]) => fs.writeSync(1, `${key} ---> ${value}\n`))
// Print the total.
fs.writeSync(1, `total --> ${global.promises.total}\n`)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment