-
Notifications
You must be signed in to change notification settings - Fork 19
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
memory leak? #25
Comments
Hi @FDiskas 😀 Thanks for reporting the problem. I tried to reproduce it in my local environment, but it doesn't work. When using this middleware, did the memory gradually increase, and was the server restarted by OOM? Can you elaborate on the attached graph? |
Hi, before the memory was slowly increasing over time. Thous spike drop downs was probably because of the restart. The project is running within a docker container in aws. Did not investigated deeper. Just noticed that during development the local server stops after some time and i need to restart it. After changing to simple middleware everything works without strange crashes. |
Thank you for the explanation. 😀 Could you tell me what version of next-http-proxy-middleware you are currently using for your project? |
As I noticed that there is a new release I updated as soon as possible but didn't noticed any improvement regarding memory |
😭 |
Could be related #21 |
If possible, try applying the code like this: // as-is
export default async (req: NextApiRequest, res: NextApiResponse) => {
const session = getSession(req, res);
return new Promise((resolve) =>
httpProxyMiddleware(req, res, {
target: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: { Authorization: `Bearer ${session?.idToken}`, 'Content-Type': 'application/json-patch+json' },
}).catch(async (error) => {
initSentry();
Sentry.captureException(error);
await Sentry.flush(2000);
return resolve(error);
})
);
}; // to-be ✨
export default (req: NextApiRequest, res: NextApiResponse) => {
const session = getSession(req, res);
return httpProxyMiddleware(req, res, {
target: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: { Authorization: `Bearer ${session?.idToken}`, 'Content-Type': 'application/json-patch+json' },
}).catch(async (error) => {
initSentry();
Sentry.captureException(error);
await Sentry.flush(2000);
});
}; Test result
// Test code
export default (req: NextApiRequest, res: NextApiResponse) => httpNextProxyMiddleware(req, res, {
target: 'http://localhost:8080',
}).catch(async (error) => console.log(error));
// Test code
export default async (req: NextApiRequest, res: NextApiResponse) => new Promise(
(resolve) => httpNextProxyMiddleware(req, res, {
target: 'http://localhost:8080',
}).catch(async (error) => resolve(error)),
); |
I will try at Monday let you know |
Looks like still something is wrong. import { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from '@auth0/nextjs-auth0';
import httpProxyMiddleware from 'next-http-proxy-middleware';
import * as Sentry from '@sentry/node';
import { initSentry } from 'src/utils/sentry';
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
export default async (req: NextApiRequest, res: NextApiResponse) => {
const session = getSession(req, res);
try {
return await httpProxyMiddleware(req, res, {
target: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: {
Authorization: `Bearer ${session?.idToken}`,
'Content-Type': 'application/json-patch+json',
},
});
} catch (error: any) {
initSentry();
Sentry.captureException(error);
await Sentry.flush(2000);
return error?.message;
}
}; And after some time I get crash
|
Hi @FDiskas, Please do not return promise(await function) 😭 export default async (req: NextApiRequest, res: NextApiResponse) => { // <-- `fix to export default (req: NextApiRequest, res: NextApiResponse)`
const session = getSession(req, res);
try {
return await httpProxyMiddleware(req, res, { // <-- fix to `return httpProxyMiddleware`
target: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: {
Authorization: `Bearer ${session?.idToken}`,
'Content-Type': 'application/json-patch+json',
},
});
} catch (error: any) {
initSentry();
Sentry.captureException(error);
await Sentry.flush(2000);
return error?.message;
}
}; |
The reason is simple. Eslint rules does that. :) But I will check that later |
Tested - still memory is increasing - I used code like so export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
export default (req: NextApiRequest, res: NextApiResponse) => {
return httpProxyMiddleware(req, res, {
preserveHeaderKeyCase: true,
target: process.env.NEXT_PUBLIC_API_BASE_URL,
timeout: 3000,
headers: {
'Content-Type': 'application/json-patch+json',
},
}).catch(async (error) => {
res.end(error.message);
});
}; I builded app and then started it using
attached chrome inspector and I compared between memory snapshots and the main issue is pointing to |
JS memory can grow and shrink while the process is running. Over time, unused memory is removed by the GC. export default (req: NextApiRequest, res: NextApiResponse) => {
return httpProxyMiddleware(req, res, {
preserveHeaderKeyCase: true,
target: process.env.NEXT_PUBLIC_API_BASE_URL,
timeout: 3000,
headers: {
'Content-Type': 'application/json-patch+json',
},
}).catch((error) => { // <!-- here
res.end(error.message);
});
}; If the catch does not return a promise result, the promise will not be removed by the GC and will persist. |
Thank you for good explanation. |
This library can be used in a variety of ways, making it difficult to give specific examples. However, if a good reference is recorded like this issue, I think I can refer to it later. |
I was using this module like so:
And as you can see in memory usage graph it is spikes and some server restarts.
But when I switched to middleware like so
the memory usage becomes stable. Also got correct response headers from API like 404
The text was updated successfully, but these errors were encountered: