msw: "Warning: Possible EventEmitter memory leak detected" when using with NextJS
Describe the bug
I’ve implemented client and server side mocks as per the docs. Using GraphQL queries and mutations in a NextJS application which I’ve bootstrapped from _app.tsx which is about as global as I can get without a custom server.
With each save the application is re-compiled and refreshed in the browser.
Beyond the performance details listed here, the isomorphic mocks are working nicely.
Server side: Depending on how many routes are visited, or how many changes are made. MSW pretty quickly stops responding and warns of a memory leak with too many open handlers, message from server-side console as below:
“MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added to [IncomingMessage]. Use emitter.setMaxListeners() to increase limit”
This doesn’t happen with mocks off.
Client In the browser, after navigating to about 5 different routes, the browser stop responding. Chrome is timing out completely, doing nothing at all on route changes. The message in Chrome is:
“waiting for available socket”.
When i use browser tools to end the service worker, normal performance resumes.
Problem doesn’t happen with mocks off.
In NextJS Dev mode, there is hot module reloading going on every save… I think this is where the problem stems from as this uses sockets.
I think there’s an issue with the service worker and the socket reloads.
Once I kill the service worker, the server-side resumes - just with the memory leak warning.
Environment
msw: 0.29.0
nodejs: 14.17.0
npm: 6.14.13
next: 10.2.3
Please also provide your browser version.
Chrome: Version 91.0.4472.101 (Official Build) (x86_64)
To Reproduce
Steps to reproduce the behavior: 1 - Load multiple, routes in a NextJS app 2 - after 5 different route loads there are already 1 end listeners 3 - App performance drops to unusable 4 - Use application panel to end the service worker in the browser & app responds as normal
Expected behavior
No memory leaks
Screenshots
If applicable, add screenshots to help explain your problem.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 16
- Comments: 26 (11 by maintainers)
The fix has been released in 0.32.1 (see the release notes). Could you please update and let us know if the issue is gone?
Looked into this as well. Here’s a reproducible test case: https://github.com/webpro/msw-next
To reproduce the issue:
npm install && npm run dev
Seeing suspicious logs for requests such as:
In another application it also captures requests for images (they are served from the local
public
folder).Tried a few versions of Next.js (v9.2 v10.2 v11.0) - all the same issue.
Even when using another hostname and port for the requests (added to
/etc/hosts
), it looks like it still starts capturing all requests fromlocalhost
(but also correctly captures the request for the other domain).Then I tried to downgrade msw. It seems this leak is introduced in v0.25.0, as things start to work properly with v0.24.4 (and lower).
So to get a working version in the repo above, use
npm install msw@0.24.4
Edit: also when downgrading msw to v0.24.4 in a pretty large project with a custom msw setup, the memory leak is no longer present.
I’ve released the fix in
@mswjs/interceptors@0.12.3
(Release notes). Could somebody please use that version and verify that the memory leak in Node.js is resolved by this fix?I’ll prepare a pull request that cleans up the attached event listeners from the
IncomingMessage
as a part of thegetIncomingMessage
function. I’ve tested this change locally and confirm thatres._events
(stream._events
in the latest interceptors) is empty once the function is done extracting the response body.My colleague noticed a workaround:
Check the “Update on reload” checkbox.
This prevents the worker from stalling the application… but doesn’t solve the underlying problem.
The event listener leak has been fixed in #822 and the development server being not responsive has been addressed in #834. This issue should be resolved now.
Please update to
msw@0.33.1
and let me know if you can still reproduce this. I’ll close the issue until further notice, as I can’t reproduce any issues when working with NextJS now.Hey @JReinhold, the workaround with NextJS is to stop the worker every time the MyApp Component (_app.tsx) is unmounted:
I am not that confident because I was concerned on a few race conditions for http requests, but I have tested many route changes + hot reload, and it all seems to work fine. The requests are also being mocked correctly in my case.
You could try the router.events, but I found them to be less reliable than useEffect.
@andrelas1 can you in the meantime share how you built your workaround in practice?
That would be amazing, @andrelas1. Let us know what you find, perhaps we can account for this on the MSW side, or at least in the official MSW NextJS usage example. Thank you.
Hey @kettanaito I was facing that same issue but after trying the
@mswjs/interceptors@0.12.3
, it seemed to have solved the issue!I will keep working with the new version and if it pops something not expected, I will let you know.
I guess we just need to wait for the release of the new msw version 😃
Thanks for the fix!!
Sorry I didn’t have the time to try this, but thank you so much for your effort to fix it!
If what I found is correct, should this be better reported as an issue of mswjs/interceptors, instead of this repository ?