Too many subscriptions to Server.close event cause a OOM?
LRagji opened this issue · 12 comments
Checks
- I understand project setup issues should be asked on StackOverflow or in GitHub Discussions.
- I updated to latest
http-proxy-middleware
.
Describe the bug (be clear and concise)
This is a observation which is pointing out to a potential OOM, in our application we are using this package as shown in your first example.
import * as express from 'express';
import { createProxyMiddleware, Filter, Options, RequestHandler } from 'http-proxy-middleware';
const app = express();
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
app.listen(3000);
and we are stress testing this API with multiple requests, it has been observed that following code is attaching multiple event handlers on the server.close
, which prompts node to think its a memory leak. MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connected listeners added to [NativeConnection].
The obvious way to fix this is to create the middleware once capture it in a variable and use that as shown in your 3rd example on the readme page instead of recreating the middleware every time as shown by the first example.
If our conclusion is right then i think you should remove inline creation of the middleware from your examples, so that other don't fall for the same issue.
Step-by-step reproduction instructions
1. Create the example one as shown in the readme page. Node v18, Install latest of this package.
2. Make sure the upstream server takes 1 second to complete the request.
3. Nuke the api with any performance tool or stress test tool.
Expected behavior (be clear and concise)
Should not see this warning in the console MaxListenersExceededWarning: Possible EventEmitter memory leak detected
How is http-proxy-middleware used in your project?
As shown in example 1:
import * as express from 'express';
import { createProxyMiddleware, Filter, Options, RequestHandler } from 'http-proxy-middleware';
const app = express();
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
app.listen(3000);
### What http-proxy-middleware configuration are you using?
```typescript
Default
What OS/version and node/version are you seeing the problem?
Node v18
OS: Node official container.
Additional context (optional)
No response
same issue.
Any updates on this?
I got the same error when used a proxy in Parcel
We're also getting this warning message, @LRagji, but the code you linked should add the on-close-event-listener only once as this.serverOnCloseSubscribed
will be set:
if (server && !this.serverOnCloseSubscribed) {
server.on('close', () => {
debug('server close signal received: closing proxy server');
this.proxy.close();
});
this.serverOnCloseSubscribed = true;
}
Were you able to debug it?
@rene-leanix If i remember this correctly, Its about adding the event handler every-time a request is made..
@LRagji, I just found out that in our code we're calling createProxyMiddleware()
not just once but multiple times! That's the reason why we ran into the error message. Maybe its the same for others.
Its about adding the event handler every-time a request is made
But if you look at the code snippet above, I can't see how that could happen, if createProxyMiddleware()
is only called once. this.serverOnCloseSubscribed
is false
to start with and only set in this one place.
Again this was long back but i remember the HttpProxyMiddleware
class was getting initialised for every request, which was triggering a lot of handlers.. don't remember how but the default code itself was not working, is that first example working for you? also they released a new release in April so not sure if things in pipeline changed anywhere....
I tried to reproduce it as described in your initial post by spinning up that simple app and executing more than 10 curl requests simultaneously against that endpoint, but all requests succeeded and now warning was logged. I also debugged the code you linked to and both the constructor
and the server.on('close')
-call are executed once. This was confirmed by adding logs to the both places in the http-proxy-middleware dist code.
Could your load-testing setup have triggered a restart of the server between requests?
@Jokero, @fetis, @khoale-groove or @f4z3k4s: can any of you confirm that this issue happens apart from createProxyMiddleware()
being called multiple times in your code?
@rene-leanix What version are you testing?, and if your don't mind can you share your code which was calling create method over and over again? I can see a lot of changes that happened for those specific method 'create proxy' in the library for different version
@LRagji, I am using the latest versions for http-proxy-middleware
(3.0.0) and express
(4.19.2), so maybe it was fixed recently.
Regarding the code calling the API, I used the quick & dirty
curl http://localhost:3000/api & curl http://localhost:3000/api & ... & curl http://localhost:3000/api
with more than 10 curl statements.
@rene-leanix We call it on application startup to configure and create proxies middleware, smth like this
function proxyHelper() {
// our custom code and reconfiguration
return createProxyMiddleware();
}
app.use(proxyHelper())