-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove the dynamicRequire hack to fix scope memory leak #2515
Conversation
JS tooling is hard. You never know when something changes and breaks your own workaround ¯_(ツ)_/¯ |
@kamilogorek You're right, even more so when it's about js modules. The ecosystem is in a weird state right now between what is official spec and what is invented userland legacy stuff, what is supported, and how different bundlers decides ton interpret and implement it. It's a goddamn mess, but we'll get to a point where it's all cleared up someday... I hope 😅 Thanks for merging and releasing this so quickly ✌️ |
@Madumo do you have your test cases still laying around by any chance? Unfortunately, the builds are now failing for react-native, as bundler tries to optimize If so, can you test out this silly change?: const req = require;
const domain = req('domain'); It works around the react-native bundler correctly, but we need to be sure that it works fine with webpack as well. |
Ref: #2521 |
Ha! Fixed webpack, broke metro. Dammit. I'll check! |
That bug has been discussed in #1762. When bundling
@sentry/node
with webpack, it causes a sentry to leak memory.The problem resides in the
dynamicRequire
function. This function expects themodule.require
function to exist, but when bundled with webpack it doesn't. When we use it to require thedomain
module, which is needed to clone the scope instance, it throws an error and sentry fallback to using the global scope instance.Each incoming requests then use the same scope instance and attach a new event processor callback to it. Since those event processors are never unassigned and depend on the whole scope object to be garbage collected, their closure which capture a lot of stuff (like the request object) stays in memory.
Recap
dynamicRequire is used to load the
domain
modulemod.require is undefined
What the mod object looks like
dynamicRequire
is making the assumption that themodule
is the one from node, but when bundled by webpack it's an object provided by webpack that doesn't have theModule
__proto__
.dynamicRequire
throws an error sincemod.require
is undefined andgetHubFromActiveDomain
end up usinggetHubFromCarrier(registry)
instead ofgetHubFromCarrier(activeDomain)
I guess this might also cause bugs when processing an error since all the event processors previously added by previous requests will be called? 🤔
To fix this issue I replaced
dynamicRequire
withrequire
, and it now works, no more leak! 🎉I guess the
dynamicRequire
hack was only needed with older versions of webpack and now isn't needed anymore.